Perl变量初始化错误在子例程中使用
所以我有一个情况,我有一个有两个命名参数的函数,但是如果两者都被使用,这个函数就需要终止。我不确定这是否是一个bug,或者是否有一些我不了解的关于Perl变量的内在内容 以下是简化代码:Perl变量初始化错误在子例程中使用,perl,subroutine,Perl,Subroutine,所以我有一个情况,我有一个有两个命名参数的函数,但是如果两者都被使用,这个函数就需要终止。我不确定这是否是一个bug,或者是否有一些我不了解的关于Perl变量的内在内容 以下是简化代码: #!/usr/bin/perl use strict; use warnings; use Data::Dumper; foreach my $number (1..5) { fooBar(foo => $number); } sub fooBar { my %args = (
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
foreach my $number (1..5)
{
fooBar(foo => $number);
}
sub fooBar
{
my %args = (
foo => undef,
bar => undef,
@_
);
my $foo = $args{foo} if defined $args{foo};
my @bar = @{$args{bar}} if defined $args{bar};
print Dumper(\@bar);
if (defined $foo)
{
die('fooBar() received both a foo and a bar and didn\'t know which to use!') if @bar;
push(@bar, $foo);
}
print Dumper(\@bar);
return (\@bar);
}
# > $VAR1 = [];
# > $VAR1 = [
# > 1
# > ];
# > $VAR1 = [
# > 1
# > ];
# > fooBar() received both a foo and a bar and didn't know which to use! at ./example.pl line 27.
以下是我的解决方案:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
foreach my $number (1..5)
{
fooBar(foo => $number);
}
sub fooBar
{
my %args = (
foo => undef,
bar => undef,
@_
);
my $foo;
my @bar;
$foo = $args{foo} if defined $args{foo};
@bar = @{$args{bar}} if defined $args{bar};
print Dumper(\@bar);
if (defined $foo)
{
die('fooBar() received both a foo and a bar and didn\'t know which to use!') if @bar;
push(@bar, $foo);
}
print Dumper(\@bar);
return (\@bar);
}
# > $VAR1 = [];
# > $VAR1 = [
# > 1
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 2
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 3
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 4
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 5
# > ];
我的问题是,为什么这能解决问题?在第一个示例中,第一次调用
fooBar()
时,@bar
正在初始化,尽管if条件失败。在第二次循环中,@bar
以某种方式保留了第一次循环中的信息,但它并不抱怨被重新初始化。在我看来,要么a)@bar
应该在子例程完成后擦除(这是我所期望的),要么b)@bar
不应该在它失败后初始化(如果定义了测试),要么c)@bar
应该抱怨它正在通过循环第二次重新初始化。我很困惑,这只是一个bug吗?这只会有条件地创建一个新变量,并可能导致奇怪的结果:
my $foo = $args{foo} if defined $args{foo};
有这样的说法:
注意:my、state或our modified with语句修饰符条件或循环构造(例如my$x if…)的行为未定义。my变量的值可能是未定义的、任何先前指定的值,或者可能是任何其他值。不要依赖它。未来版本的perl可能会做一些与您试用的perl版本不同的事情。这里有龙
不要试图定义$foo
变量;只需使用$args{foo}
。或者无条件地完成任务;分配undef没有什么错。啊,你想在Perl中找到bug吗?您真的理解Perl在代码中所理解的内容吗?;)我认为lazyif子句中的赋值(do{my$var=value;}if-value);应该会引起问题不要做我的。。。如果
。但实际发生的情况(目前,文档中将其标记为可能发生更改)是my
具有编译时和运行时两种效果;if可以跳过运行时效果,使perl不知道它需要在作用域末尾重新初始化变量。在这种情况下,也可以尝试perlcritic
:它说:在第22行第5列的条件语句中声明的变量。在条件之外声明变量。(严重程度:5)(第23行也是如此)非常有趣。我用这种方式格式化代码还有其他原因,但在我的示例中并不明显,尽管仔细看一下,我。。。不知道这些原因是什么。也许我会把它扔掉,看看有什么坏掉了。感谢您的回复:)@JasonHamje,文档。。。你知道你应该做什么;)@我想他是在向Jason说明为什么编写自己的代码很好。因为Jason说他格式化代码还有其他原因,但他记不起来了。如果他把它们记录下来,他就不必记得了。@gaussblurinc;够公平,够公平:P@ysth嗯,英国的讽刺很简单。。呃,不,我是说OP以后应该读它