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


Prototyping Squirrels

There’s a new article on ExplorerCanvas: Interactive Web Apps. It’s all about chasing squirrels with a web page. So far so good.

But I noticed that the author is using Prototype. Good stuff! Great way to cut down on having to do a lot of stuff yourself.

Yet reading through the article, it seems that the only thing it’s being used for is the $() function and the Ajax bits. I base this on the fact that on page 2, the wheel (in the form of event handling) is completely reinvented. Why bother including all of Prototype if you’re going to ignore large bits of it? You can cut’n’paste $() in a few lines of code instead…

Personally, I’d spend a short amount of time reading a couple of the really good articles on Prototype:

Remember: Prototype isn’t just for Ajax.