我有这段代码:
#!/usr/bin/perl
use strict;
use warnings;
my $judge_exes = {
"^A" => "foo",
"^B" => "bar",
"^C" => "baz",
};
sub get_judge {
my ($test_id) = @_;
my $exe = undef;
while (my ($regex, $judge) = each %$judge_exes) {
if ($test_id =~ /$regex/) {
$exe = $judge;
last;
}
}
if ($exe) {
return $exe;
} else {
return "Undefined!";
}
}
print get_judge("A1");
print get_judge("B2");
print get_judge("C3");
(ideone:http://ideone.com/slxebG)
我希望获得输出foobarbaz
,但最终得到fooUndefined!baz
。但是,当我注释掉last
语句时,我得到了正确的行为:
#!/usr/bin/perl
use strict;
use warnings;
my $judge_exes = {
"^A" => "foo",
"^B" => "bar",
"^C" => "baz",
};
sub get_judge {
my ($test_id) = @_;
my $exe = undef;
while (my ($regex, $judge) = each %$judge_exes) {
if ($test_id =~ /$regex/) {
$exe = $judge;
# last;
}
}
if ($exe) {
return $exe;
} else {
return "Undefined!";
}
}
print get_judge("A1");
print get_judge("B2");
print get_judge("C3");
(ideone:http://ideone.com/QJpxbK)
为什么会这样? (我使用的是Perl 5.16.2,但问题也存在于5.10.1以及无论是谁使用的。)
last
只是突破while
循环,这就是我想要的。$exe
似乎不是一个替代的假值,导致我遇到错误的if-branch。 (我可以提早回来,这会更好,但我仍然不明白这个原因。)我只是犯了一些愚蠢的非Perl相关错误吗?
答案 0 :(得分:1)
你变得困惑。我不确定混淆在哪里,但你必须知道each
运算符在调用之间保持其状态。这意味着last
循环内的while
将不会终止迭代。相反,它将在下一次遇到它时继续停留的地方。
你也应该保留双引号,因为它们插入任何标量或数组变量或反斜杠控制字符。
以下是我建议你编写算法的方法
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my $judge_exes = {
'^A' => 'foo',
'^B' => 'bar',
'^C' => 'baz',
};
say get_judge('A1', $judge_exes);
say get_judge('B2', $judge_exes);
say get_judge('C3', $judge_exes);
say get_judge('D4', $judge_exes);
say get_judge('E5', $judge_exes);
sub get_judge {
my ($test_id, $judges) = @_;
for my $re ( keys %$judges ) {
return 1 if $test_id =~ /$re/;
}
'Undefined!';
}
<强>输出强>
1
1
1
Undefined!
Undefined!
答案 1 :(得分:0)
哦,看起来行为是explained here:
在标量上下文中使用
keys %hash
返回散列中的键数,并重置与散列关联的迭代器。如果使用last
提前退出循环,则可能需要执行此操作,以便在重新输入时,哈希迭代器已重置。
没想到 - 我以为each
会重置迭代器。