【发布时间】:2011-08-09 21:11:17
【问题描述】:
看来清理垫子太早了:
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=
或者,如果有人能指出我正在做的蠢事,我将不胜感激。我什至在第一个闭包和外部闭包之间创建了增量变量,但它们也被重置了。即使在最里面的闭包上设置 references,在命名的子范围内也得不到任何东西!
这里涉及的整个代码是 500 行。包含代码是不切实际的。
【问题讨论】:
-
“清理垫”是什么意思?你期望得到什么输出?
descend和each_value方法到底有什么作用? -
@Jack Maney,当我打印出中间循环中的值时,
$found是1和$where是一个哈希值。当我在搜索中打印这些值时,它们都被重置为其原始值,就好像它们是本地化的包变量(它们不是)。所以我将它们设置在内部闭包中,它们保留了中间的值,但它们完全设置回search中的原始值。 -
Axeman:perl 文档多年来一直警告不要使用这种条件初始化 - 请参阅“Here be dragons”。在 perlsyn。基本上,您绕过了
my的运行时效果,这通常不是您想要的(并且在未来的 perl 版本中可能会发生变化)。 -
就远距离的操作而言,我猜你只是因为
my ... if没有按照你的意图做而导致的直接逻辑错误。但是如果没有一个独立的例子来尝试,就不可能说。 -
@ysth,是的,现在这很有意义,通常在语句末尾挂一个条件后缀会阻止语句的任何部分运行,并且它会使用 my .我认为失败在于
strict没有抱怨,因为——你有点没有声明变量。所以让我直截了当地说:它绕过strict并成为一个 package 变量?
标签: perl lexical-scope