Проблема подсчета ссылок с Perl 5.12.3? - PullRequest
1 голос
/ 10 августа 2011

Кажется, он слишком рано очищает подушку:

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 ]

2 голосов
/ 10 августа 2011

Было бы очень хорошо, если бы вы могли предоставить полный, работоспособный пример.

Удар в темноте: помогает ли постороннее использование $, найденное во внешнем анонимном подпрограмме (например, $found if 0;)?

1 голос
/ 10 августа 2011

Не используйте 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.

...