Perl 5.12.3的引用计数问题?

时间:2011-08-09 21:11:18

标签: perl lexical-scope

它似乎太早清理了垫子:

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行。包含代码是不切实际的。

2 个答案:

答案 0 :(得分:2)

如果你能提供一个完整的,可运行的例子,那将是非常好的。

在黑暗中刺伤:在外部匿名子(例如$found if 0;)中找到$外来使用是否有帮助?

答案 1 :(得分:1)

不要将my与语句修饰符一起使用!

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

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

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

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

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

做了这个伎俩。它不仅用另一种方法清理了我遇到的问题,而且还清除了search中的问题。