我正在尝试分析一段包含以下内容的Perl代码:
unless( @{$avl->Rates() || []} ) {
if(!$nobar) { push @rptmp, 'BAR' unless @rptmp; }
}
我认为我理解的内心动作。这意味着“如果$ nobar为false(在这种情况下为0),则将字符串'BAR'添加到数组@rptmp
,除非@rptmp
已存在。”
我遇到问题的部分是第一个“除非”条件:unless ( @{$avl->Rates() || []} )
。 $avl->Rates()
是一个返回列表的函数(或者是指向列表的指针?)。但对我来说真正令人困惑的部分是|| []
。这是“或”某事,因此除非$avl->Rates()
没有返回任何内容,否则不会选中它。但我不确定它是做什么的,特别是空方括号。如果它返回一些空的东西,它不会总是错误吗?还有,有更好的,或者至少更清晰的方式来写这个吗?
答案 0 :(得分:5)
所以除非
,否则不会选中它$avl->Rates()
没有返回
它不可能在标量上下文中返回任何内容。据推测,它返回对数组的引用或undef。 unless (@{ $avl->Rates })
在后一种情况下会失败,因此编码器决定在这种情况下使用对空数组的引用。
[]
大致相当于
# Create an array, and return a reference to it.
do { my @anon; \@anon }
这有点浪费,但
if (!@{ $avl->Rates() || [] }) {
...
}
是常用的,因为它比
短my $rates = $avl->Rates();
if (!$rates || !@$rates) {
...
}
以下内容更清晰,避免在不需要时调用Rates
:
if (!$nobar && !@rptmp) {
my $rates = $avl->Rates;
push @rptmp, 'BAR'
if !$rates || !@$rates;
}
答案 1 :(得分:2)
嗯。让我们看看这个。我认为这是可怕的Perl,但其他人显然不同意。有很多人遇到unless
问题(仅仅意为if not
),在这种情况下,我表示同情:那里发生的事情太多了
这是整个事情
unless ( @{ $avl->Rates() || [] } ) {
if ( !$nobar ) { push @rptmp, 'BAR' unless @rptmp; }
}
首先,我会像这样提取Rates
的电话
my $rates = $avl->Rates();
unless ( @{ $rates || [] } ) {
if ( !$nobar ) { push @rptmp, 'BAR' unless @rptmp; }
}
我不知道$avl
可能是什么,但看起来它的Rates
方法会返回数组引用或 false 值 - 可能undef
。所以表达式$rates || []
默认任何 false 来引用一个enpty数组。现在封闭的@{ ... }
可以安全地取消引用它
测试是数组是否为空,我会写
unless ( $rates and @$rates )
即。 除非Rates
方法返回 true 值并且它是对非空数组的引用
现在我们有另一个unless
的内部声明,除了这次它写成if not
,并且里面有一个真实的unless
if ( !$nobar ) {
push @rptmp, 'BAR' unless @rptmp;
}
内部陈述很简单。除非数组为空,否则它会测试@rptmp
true ,如果它为空,则将BAR
推送到仅
附带的条件检查可能是一个选项$nobar
,如果它是 true ,那么BAR
永远不会被推到数组上,无论其他条件是什么
我会以这种方式重构整个方法,分别提取方法调用并在整个过程中使用unless
my $rates = $avl->Rates;
unless ( $rates and @$rates) {
unless ( $nobar ) {
push @rptmp, 'BAR' unless @rptmp;
}
}
如果您是unless
- 恐惧症,那么这里的版本仅使用if
,但我觉得它不太可读
my $rates = $avl->Rates;
if ( not $rates or @$rates == 0 ) {
if ( not $nobar ) {
push @rptmp, 'BAR' if @rptmp == 0;
}
}
我希望有帮助