Почему Time :: HiRes :: stat список рассылки подписывается? - PullRequest
7 голосов
/ 03 декабря 2011

Я не могу понять, что здесь происходит. Откуда взято 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"'

$

Это пакет Perl Debian версии 5.14.2-5. Я получаю те же результаты с 5.10.1-17squeeze2.

Как V2, выше, производит 8? Я неправильно понимаю синтаксис Perl или мне просто нужно подать отчет об ошибке?

edit: как говорит @cjm, это ошибка. Это исправлено в Time-HiRes-1.9725 согласно отчету.

Ответы [ 2 ]

3 голосов
/ 03 декабря 2011

Это определенно ошибка, хотя я не уверен, в ядре ли это Perl или в Time :: HiRes.Я получаю те же результаты с Perl 5.14.2 на Gentoo (а также с 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 first.

Примечание. Несмотря на то, что они обрабатываются одинаково, они генерируют разные коды операций (из-за разницы между вызовом встроенного и определяемого пользователем суб-кода):

$ 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
0 голосов
/ 08 декабря 2011

Я никогда не использовал выполнение командной строки, поэтому я говорю о странностях в ее работе.

Я видел неожиданные результаты при использовании индекса функции, которая должна возвращать массив.

$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";

Я использую Perl ActiveState на WinXP, поэтому мои результаты могут не совпадать. Тем не менее, я думаю, что это может быть полезно попробовать в очень простом коде, чтобы увидеть, что он делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...