Perl的触发器运算符有bug吗?它有全局状态,如何重置它?

前端之家收集整理的这篇文章主要介绍了Perl的触发器运算符有bug吗?它有全局状态,如何重置它?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我很失望。 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

每个递归深度是一个单独的..运算符。

猜你在找的Perl相关文章