arrays - 为什么 Time::HiRes::stat 打破列表下标?

标签 arrays perl

我无法弄清楚这里发生了什么。下面的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 上使用 Perl 5.14.2(以及 5.8.9 和 5.10.0)得到相同的结果。你有没有注意到你在下标里放什么并不重要?

$ perl -MTime::HiRes=stat -e 'print +(stat("foo"))[215.4], "\n"' 
215.4
$ perl -MTime::HiRes=stat -e 'print +(stat("foo"))["bar"], "\n"'
bar

我可能会 report it in 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

关于arrays - 为什么 Time::HiRes::stat 打破列表下标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8367789/

相关文章:

java - 二维数组无法移动

c++ - 从 bash 拆分的流是否可以转置为其他语言?

perl - 如何在bat文件中指定Cygwin模式下需要调用的脚本?

regex -\D在Perl正则表达式中做什么

c - 打印用户输入数组

javascript - 对对象数组内的对象数组中的值进行排序

php in_array() 或 array_search() 不工作