1

似乎它清理垫太早了:

sub search { 
    my ( $self, $test ) = @_;
    my $where;
    my $found   = 0;
    my $counter = 0;

    $self->descend( pre_each => sub {
        my $lvl = shift;
        my $ev_return 
            = $lvl->each_value( sub {
               $counter++;
            my ( $name, $value ) = @_;
            say "\$name=$name";
            say "\$value=$value";
            return 1 unless $found = $test->( $value );
            $where = { key => $lvl, name => $name, value => $value };
            # when any intermediate function sees QUIT_FLAG, it 
            # knows to return control to the method that called it.
            return QUIT_FLAG; 
        });
        say "\$found=$found";
        say "\$where=$where";
        return $ev_return;      
    });
    say "\$counter=$counter";
    say "\$found=$found";
    say "\$where=$where";
    return unless $found;
    return $where;
}

我得到的是:

...
$found=1
$where=HASH(...)
$counter=0
$found=0
$where=

或者,如果有人能指出我正在做的蠢事,我将不胜感激。我什至在第一个闭包和外部闭包之间创建了增量变量,但它们也被重置了。即使在最里面的闭包上设置引用,在命名的子范围内也得不到任何东西!

这里涉及的整个代码是 500 行。包含代码是不切实际的。

4

2 回答 2

2

如果您能提供一个完整的、可运行的示例,那就太好了。

暗中刺探:在外部匿名子(例如)中额外使用 $found 是否有帮助$found if 0;

于 2011-08-10T02:51:02.943 回答
1

不要使用mywith 语句修饰符!

问题出在一个被调用的范围内。忘记了使用my语句修饰符的警告后,我编写了以下代码:

my $each   = shift if @_ == 1;
my %params = @_ unless $each;

第一次经历@_了一个争论。它将第一个值分配给$each。第二次通过,有更多参数,它跳过my. 所以当前范围内没有声明,所以它只是重用了我上次分配的 sub ,并且没有保存任何内容,%params因为$each它引用的一个值。

很奇怪,但正如 ysth 指出的那样,perlsyn警告不要这种行为。我想我曾经知道这一点,但多年来已经忘记了。切换到

my ( %params, $each );
if ( @_ == 1 ) { 
    $each = shift;
}
else { 
    %params = @_;
}

成功了。它不仅清理了我用另一种方法遇到的问题,而且清理了search.

于 2011-08-10T15:26:12.487 回答