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