我很失望。 OK,所以这可能是我发现的最有趣的
Perl错误。即使今天我正在学习关于Perl的新东西。本质上,触发器运算符,它返回假,直到左手边返回真,然后真直到右手边返回假保持全局状态(或这是我假设)。
我可以重置它(也许这将是一个很好的补充Perl 4-esque几乎没有使用reset())?或者,没有办法安全地使用这个操作符?
我也不看这个(全局上下文位)在perldoc perlop的任何地方记录这是一个错误?
码
use feature ':5.10'; use strict; use warnings; sub search { my $arr = shift; grep { !( /start/ .. /never_exist/ ) } @$arr; } my @foo = qw/foo bar start baz end quz quz/; my @bar = qw/foo bar start baz end quz quz/; say 'first shot - foo'; say for search \@foo; say 'second shot - bar'; say for search \@bar;
扰流板
$ perl test.pl first shot foo bar second shot
解决方法
有人能澄清文件的问题吗?清楚地表明:
Each ".." operator maintains its own boolean state.
“每个”意味着什么,有一些模糊,但我不认为文件将很好地服务于一个复杂的解释。
注意Perl的其他迭代器(每个或标量上下文glob)可能导致相同的问题。因为每个的状态都绑定到一个特定的哈希,而不是特定的代码位,每个可以通过调用(即使在void上下文中)哈希上的键来重置。但对于glob或..,除了通过调用迭代器,直到它被重置,没有重置机制。示例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,c: got: a got: b globbing d,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
每个递归深度是一个单独的..运算符。