为什么 Time::HiRes::stat 会破坏列表下标?

发布于 2024-12-19 08:46:06 字数 1395 浏览 0 评论 0原文

我不明白这是怎么回事。下面的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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

亣腦蒛氧 2024-12-26 08:46:06

这绝对是一个错误,尽管我不确定它是在 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

我可能会在 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              <
gt; const(IV 8) s ->6
-           <1> ex-list lK ->9
6              <0> pushmark s ->7
8              <1> stat lK/1 ->9
7                 <
gt; const(PV "foo") s ->8
a        <
gt; 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              <
gt; 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                    <
gt; const(PV "foo") sM ->9
-                    <1> ex-rv2cv sK ->-
9                       <
gt; gv(*stat) s ->a
c        <
gt; const(PV "\n") s ->d
-e syntax OK

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              <
gt; const(IV 8) s ->6
-           <1> ex-list lK ->9
6              <0> pushmark s ->7
8              <1> stat lK/1 ->9
7                 <
gt; const(PV "foo") s ->8
a        <
gt; 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              <
gt; 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                    <
gt; const(PV "foo") sM ->9
-                    <1> ex-rv2cv sK ->-
9                       <
gt; gv(*stat) s ->a
c        <
gt; const(PV "\n") s ->d
-e syntax OK
送你一个梦 2024-12-26 08:46:06

我从未使用过命令行执行,所以我谈到了它的工作原理。

在应该返回数组的函数上使用下标时,我看到了意想不到的结果。

$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,所以我的结果可能不一样。尽管如此,我认为用非常简单的代码尝试一下看看它的作用可能会很有用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文