Categories
Uncategorized

Perl List Slice Weirdness

A colleague at work just found this little gem in File::Copy::Recursive:

  my $two = join '-', ( stat $cur )[0,1] || '';

That should pick out the device and inode, join them with a hyphen and set $two to the empty string if the stat failed. However, there’s a precedence problem:

  # Intended code.
  my $two = join( '-', ( stat $cur )[0,1] ) || '';
  # Actual code.
  my $two = join '-', ( ( stat $cur )[0,1] ) || '';

Spot the difference? The || bit applies to the result of the list slice. But what happens when you use || on a list slice? Let’s look at the debugger…

    DB<1> x @statinfo = stat '/etc/hosts'
  0  2050
  1  327794
  2  33188
  3  1
  4  0
  5  0
  6  0
  7  332
  8  1089379886
  9  1134738486
  10  1134738486
  11  4096
  12  8
    DB<2> x @statinfo[0,1]
  0  2050
  1  327794
    DB<3> x @statinfo[0,1] || ''
  0  327794
    DB<4> x @statinfo[0,1,2] || ''
  0  33188

So it appears that putting a list slice into scalar context always returns the last element of the list. Weird. More info (including examples at perldoc/C-style Logical Or).

Hopefully, he’ll file a bug report as it was actually tripping him up…

Update: RT#19205

2 replies on “Perl List Slice Weirdness”

You are surprised about that? I’d expect any seasoned Perl 5 programmer to know that neither @a = @b || @c nor @a = ( 1, 2 ) || ( 3, 4 ); DWIMs – what you have is just an instance of this. That you generated the list using a slice is a red herring.

Maybe you need to re-read Japhy’s famous “List” is a Four-Letter Word article? 🙂

I doubt this will be changed in Perl 5… it’s fixed in Perl 6, though.

One more point: the || '' bit is dead code.

$ perl -le'print defined join "-", ()'
1

join always returns a string – when you join nothing, it returns an empty string, not undef.

I did know that lists don’t work like that at all; I was just surprised by the combination of the list slice. I’m just pleased to say that it wasn’t in my code. 🙂

OTOH, I’m always glad that I can learn more about the language, so many years after starting.

Leave a Reply to Aristotle Pagaltzis Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s