Может кто-нибудь уточнить, в чем проблема с документацией? Это четко указывает:
Each ".." operator maintains its own boolean state.
Существует некоторая неопределенность в том, что означает "каждый", но я не думаю, что документация будет хорошо подкреплена сложным объяснением.
Обратите внимание, что другие итераторы Perl (each
или скалярный контекст glob
) могут привести к тем же проблемам. Поскольку состояние для each
связано с конкретным хешем, а не с конкретным битом кода, each
можно сбросить, вызвав (даже в пустом контексте) keys
для хеша. Но для glob
или ..
нет никакого механизма сброса, кроме как вызвать итератор, пока он не будет сброшен. Пример ошибки:
sub globme {
print "globbing $_[0]:\n";
print "got: ".glob("{$_[0]}")."\n" for 1..2;
}
globme("a,b,c");
globme("d,e,f");
__END__
globbing a,b,c:
got: a
got: b
globbing d,e,f:
got: c
Use of uninitialized value in concatenation (.) or string at - line 3.
got:
Для чрезмерно любопытных, вот несколько примеров, где один и тот же .. в источнике есть другой .. оператор:
Отдельные закрытия:
sub make_closure {
my $x;
return sub {
$x if 0; # Look, ma, I'm a closure
scalar( $^O..!$^O ); # handy values of true..false that don't trigger ..'s implicit comparison to $.
}
}
print make_closure()->(), make_closure()->();
__END__
11
Закомментируйте строку $x if 0
, чтобы увидеть, что неотключения имеют одну операцию .., общую для всех «копий», с выводом 12
.
Тема:
use threads;
sub coderef { sub { scalar( $^O..!$^O ) } }
coderef()->();
print threads->create( coderef() )->join(), threads->create( coderef() )->join();
__END__
22
Потоковый код начинается с того, что состояние .. было до создания потока, но изменения его состояния в потоке изолированы от воздействия на что-либо еще.
Рекурсия:
sub flopme {
my $recurse = $_[0];
flopme($recurse-1) if $recurse;
print " "x$recurse, scalar( $^O..!$^O ), "\n";
flopme($recurse-1) if $recurse;
}
flopme(2)
__END__
1
1
2
1
3
2
4
Каждая глубина рекурсии является отдельным .. оператором.