Why does Time::HiRes::stat break list subscripting?
I can't figure out what's going on here. Where does the 8 below come from?
Time::HiRes
provides an overload of stat
which expands the times to have high-resolution (which is supported on my system).
$ perl -MTime::HiRes -e 'print +(stat("foo"))[8], "n"' # V1
1322915623
$ perl -MTime::HiRes=stat -e 'print +(stat("foo"))[8], "n"' # V2
8
$ perl -MTime::HiRes=stat -e '@a = stat("foo"); print $a[8], "n"' # V3
1322915623
That particular file doesn't have a high-resolution timestamp, but that's not the mystery: the mystery is V2, which prints 8. In fact, it always prints the number in square brackets.
The obvious answer, it parses differently, does not seem correct:
$ perl -MO=Deparse -MTime::HiRes -e 'print +(stat("foo"))[8], "n"' # V1
use Time::HiRes;
print((stat 'foo')[8], "n");
-e syntax OK
$ perl -MO=Deparse -MTime::HiRes=stat -e 'print +(stat("foo"))[8], "n"' # V2
use Time::HiRes (split(/,/, 'stat', 0));
print((stat 'foo')[8], "n");
-e syntax OK
They deparse the same (other than the different option to use Time::HiRes
).
It works fine if I use my own function in similar syntax, and I can't get the "wrong" answer even if I return something silly from my function:
$ perl -e 'sub bar() { return qw(a b c d e f g h i j) }; print +(bar)[8], "n"'
i
$ perl -e 'sub bar() { return undef }; print +(bar)[8], "n"'
$
This is Debian's perl package, version 5.14.2-5. I get the same results with 5.10.1-17squeeze2.
How does V2, above, produce 8? Am I misunderstanding Perl syntax in some way, or do I just need to file a bug report?
edit: As @cjm says, this is a bug. It has been fixed in Time-HiRes-1.9725 according to the report.
It's definitely a bug, although I'm not sure whether it's in core Perl or in Time::HiRes. I get the same results with Perl 5.14.2 on Gentoo (and also with 5.8.9 and 5.10.0). Have you noticed that it doesn't matter what you put in the subscript?
$ perl -MTime::HiRes=stat -e 'print +(stat("foo"))[215.4], "n"'
215.4
$ perl -MTime::HiRes=stat -e 'print +(stat("foo"))["bar"], "n"'
bar
I'd probably report it in Time::HiRes first.
Note: While they deparse the same, they do generate different opcodes (due to the difference between calling a built-in and a user-defined sub):
$ perl -MO=Concise -MTime::HiRes -e 'print +(stat("foo"))[8], "n"'
c <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 271 -e:1) v:{ ->3
b <@> print vK ->c
3 <0> pushmark s ->4
9 <2> lslice lK/2 ->a
- <1> ex-list lK ->6
4 <0> pushmark s ->5
5 <$> const(IV 8) s ->6
- <1> ex-list lK ->9
6 <0> pushmark s ->7
8 <1> stat lK/1 ->9
7 <$> const(PV "foo") s ->8
a <$> const(PV "n") s ->b
-e syntax OK
$ perl -MO=Concise -MTime::HiRes=stat -e 'print +(stat("foo"))[8], "n"'
e <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 271 -e:1) v:{ ->3
d <@> print vK ->e
3 <0> pushmark s ->4
b <2> lslice lK/2 ->c
- <1> ex-list lK ->6
4 <0> pushmark s ->5
5 <$> const(IV 8) s ->6
- <1> ex-list lK ->b
6 <0> pushmark s ->7
a <1> entersub[t1] lKS/TARG,1 ->b
- <1> ex-list lK ->a
7 <0> pushmark s ->8
8 <$> const(PV "foo") sM ->9
- <1> ex-rv2cv sK ->-
9 <$> gv(*stat) s ->a
c <$> const(PV "n") s ->d
-e syntax OK
I have never used the command line execution so I speak to oddities in its workings.
I have seen unexpected results when using a subscript on a function that should return an array.
$y = localtime()[5]; # failed for me (I forget just how)
but
$y = (localtime())[5]; # worked fine
This suggests to me a bug in (my implementation of) Perl. A better test might be to try it in an actual script:
use Time::HiRes qw(stat);
my @x = stat("foo");
print $x[8],"n";
I am using ActiveState's Perl on WinXP so my results may not be the same. Still, I think it may be useful to try it in very simple code to see what it does.
链接地址: http://www.djcxy.com/p/10158.html