在开发一些代码时,我运行了一些不完整的代码,其中
ìf
/else
部分仍然需要完成。然而,条件调用例程具有“副作用”,因此我希望能够跟踪基本逻辑流程。
然而,最初的
n
处的一个 if
命令似乎跳过了整个 if
... elsif
... else
语句。
考虑一下在看到效果后捕获的这个示例(它不会运行,但你明白了):
DB<5> l 3136-3164
3136 sub manage_key($$$)
3137 {
3138: my ($ks, $ID, $params) = @_;
3139: my $me = 'manage_key';
3140: my $result = 1;
3141: my ($key_type, $instance) = split_ID($ID);
3142
3143: $ks->clear_errors();
3144:b if (defined(my $PIN = $params->{(PK_PIN)})) {
3145: if (my $container = $ks->get_container($key_type, $instance, $PIN)) {
3146 #...
3147 } else {
3148: my $err = ks_error_message($ks, ': ');
3149
3150: verbose(-1, "failed to get key $ID$err");
3151: show_ks_errors($ks);
3152: $result = 0;
3153 }
3154: } elsif (my $container = $ks->_get_container($key_type, $instance)) {
3155 #...
3156 } else {
3157: my $err = ks_error_message($ks, ': ');
3158
3159: verbose(-1, "failed to get key $ID$err");
3160: show_ks_errors($ks);
3161: $result = 0;
3162 }
3163==> return $result;
3164 }
调试器会话(未设置
$params->{(PK_PIN)}
)是:
main::manage_key(./keytool.pl:3144): if (defined(my $PIN = $params->{(PK_PIN)})) {
DB<3> n
main::manage_key(./keytool.pl:3163): return $result;
DB<3> x $result
0 1
#...
DB<6> x $params->{(PK_PIN)}
0 undef
所以我的期望是
n
命令将再次在第 3154 行停止,其中 elsif
测试应该发生。但相反,该部分(实际执行的部分)已被跳过,直到复合语句结束。
我想知道:Perl 调试器会这样做,还是 Perl 编译器会优化“空”
if
,即使条件有副作用?
我应该提到:x86-64 (SLES12 SP5) 上的 Perl 5.18.2
使用
s
,而不是 n
,step 进入调试器中的子例程调用。
use warnings;
use strict;
use feature qw{ say };
sub check {
say "SUB";
return time
}
my %H = (ZERO => 0);
if (defined(my $pin = $H{MISSING})) {
say "IF";
} elsif (my $pop = $H{ZERO} * check()) {
say "ELSIF";
} else {
say "ELSE";
}
say "Done.";
您可以看到子程序仍在运行(由于副作用),但它没有显示在调试器中。
使用
n
:
perl -d 2.pl
Loading DB routines from perl5db.pl version 1.51
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(2.pl:11): my %H = (ZERO => 0);
DB<1> n
main::(2.pl:13): if (defined(my $pin = $H{MISSING})) {
DB<1> n
SUB
main::(2.pl:18): say "ELSE";
DB<1> n
ELSE
main::(2.pl:20): say "Done.";
使用
s
:
main::(2.pl:11): my %H = (ZERO => 0);
DB<1> s
main::(2.pl:13): if (defined(my $pin = $H{MISSING})) {
DB<1> s
main::check(2.pl:7): say "SUB";
main::check(2.pl:8): return time
DB<1> s
SUB
main::check(2.pl:9): }
DB<1> s
main::(2.pl:18): say "ELSE";
DB<1> s
ELSE
main::(2.pl:20): say "Done.";
DB<1> s
Done.