为什么 Time::HiRes::stat 会破坏列表下标?
我不明白这是怎么回事。下面的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
它们解析相同(除了使用 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 中修复。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这绝对是一个错误,尽管我不确定它是在 Perl 核心中还是在 Time::HiRes 中。我在 Gentoo 上使用 Perl 5.14.2(以及 5.8.9 和 5.10.0)得到了相同的结果。您是否注意到下标中输入的内容并不重要?
我可能会在 Time::HiRes 中报告第一的。
注意:虽然它们解析相同,但它们确实生成不同的操作码(由于调用内置子程序和用户定义子程序之间的差异):
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?
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(我的实现)中存在错误。更好的测试可能是在实际脚本中尝试:
我在 WinXP 上使用 ActiveState 的 Perl,所以我的结果可能不一样。尽管如此,我认为用非常简单的代码尝试一下看看它的作用可能会很有用。
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.
but
This suggests to me a bug in (my implementation of) Perl. A better test might be to try it in an actual script:
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.