为什么Time :: HiRes :: stat break list有下标?
我无法弄清楚这里发生了什么。 8下面哪里来?
Time::HiRes
提供了stat
的重载,它扩展了具有高分辨率的时间(在我的系统上支持)。
$ 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
该特定文件没有高分辨率时间戳,但这并不神秘:神秘的是V2,它打印出8个。实际上,它总是在方括号中打印数字。
显而易见的答案,它解析不同,似乎不正确:
$ 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
他们解压缩相同的(除了use Time::HiRes
的不同选项)。
如果我在类似的语法中使用我自己的函数,它会正常工作,即使我从函数返回一些愚蠢的东西,我也无法得到“错误”的答案:
$ 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"'
$
这是Debian的perl软件包,版本5.14.2-5。 我用5.10.1-17squeeze2得到了同样的结果。
V2如何产生8? 我是否以某种方式误解了Perl语法,还是只需要提交错误报告?
编辑:正如@cjm所说,这是一个错误。 根据报告,它已在Time-HiRes-1.9725中得到修复。
这绝对是一个错误,尽管我不确定它是在核心Perl还是在Time :: HiRes。 在Gentoo上(和5.8.9和5.10.0),我得到了与Perl 5.14.2相同的结果。 你有没有注意到,你在下标中放什么并不重要?
$ perl -MTime::HiRes=stat -e 'print +(stat("foo"))[215.4], "n"'
215.4
$ perl -MTime::HiRes=stat -e 'print +(stat("foo"))["bar"], "n"'
bar
我可能会首先在Time :: HiRes中报告它。
注意:虽然它们的解码方式相同,但它们确实会生成不同的操作码(由于调用内置子操作和用户定义的子操作之间的区别):
$ 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
我从来没有使用过命令行的执行方式,所以我在其工作中讲述了一些古怪的事情。
在应该返回数组的函数上使用下标时,我看到了意外的结果。
$y = localtime()[5]; # failed for me (I forget just how)
但
$y = (localtime())[5]; # worked fine
这向我暗示了(我的实现)Perl中的一个错误。 更好的测试可能是在实际的脚本中尝试它:
use Time::HiRes qw(stat);
my @x = stat("foo");
print $x[8],"n";
我在WinXP上使用ActiveState的Perl,所以我的结果可能不一样。 尽管如此,我认为在非常简单的代码中尝试一下它可能会有用。
链接地址: http://www.djcxy.com/p/10157.html上一篇: Why does Time::HiRes::stat break list subscripting?
下一篇: Issue installing Ruby rvm (error while running configure)