U. *_*ndl 2 perl optional-parameters conditional-statements
可能这是一个愚蠢的问题,但我没有看到问题(虽然假设一定有一个):
我写了一些代码;这是摘录:
use Getopt::Std;
my %options;
if (getopts('hty', \%options)) {
my @opts = split(//, 'hty');
@options{@opts} = (1, 1, 1)
if (scalar (grep { defined } @options{@opts}) == 0);
something()
if ($options{'h'});
#...
}
Run Code Online (Sandbox Code Playgroud)
代码的目的是如果三个选项均未设置,则将所有三个选项定义为已设置。然而,即使设置了一个选项(),代码似乎也会执行-h,但最终值也不是我所期望的。请参阅调试器会话的以下片段:
DB<2> x %options
0 'h'
1 1
####: so `-h` was set
DB<3> n
main::(otptest.pl:298): if (scalar (grep { defined } @options{@opts}) == 0);
DB<3> n
main::(otptest.pl:297): @options{@opts} = (1, 1, 1)
###: surprisingly the assignment seems to be executed as well
DB<3> x %options
0 'y'
1 undef
2 'h'
3 1
4 't'
5 undef
###: However at the end the values are not `1` as expected, but `undef`
Run Code Online (Sandbox Code Playgroud)
显然,程序逻辑被这种行为破坏了。错误在哪里?这可能是 Perl 5.18.2 本身的错误吗?
您看到的结果是由于 grep 中所有元素的自动激活所致:
use Data::Dumper;
my %options = qw(h 1);
print Dumper \%options;
print "empty\n" if (scalar (grep { defined } @options{qw(h t y)}) == 0);
print Dumper \%options;
Run Code Online (Sandbox Code Playgroud)
哪个输出:
$VAR1 = {
'h' => '1'
};
$VAR1 = {
'y' => undef,
'h' => '1',
't' => undef
};
Run Code Online (Sandbox Code Playgroud)
grep$_依次为其每个参数指定别名,这意味着可以通过分配给 来修改参数$_。因此,perl 将参数视为在左值上下文中使用,并自动恢复缺少的元素$options{t}和$options{y}。