我正在使用在 Science 文章中发布的工具,但它给我带来了很多麻烦,因为我对Perl并不熟悉。
代码包含:
return $equa if /\@BOUNDARY/;
我相信代码应该返回$equa
,如果它包含文本@BOUNDARY
,但它不会这样做。提供的代码是否有错误?
我正在考虑将其更改为:
if ($equa =~ /\@BOUNDARY/) {
return $equa;
}
这是否执行相同的功能?
作为参考,原始代码中的整个函数是:
sub correctBoundaryReac {
my $equa = shift;
print $equa;
return $equa if /\@BOUNDARY/;
my( $left, $arrow, $right ) = ( '', '', '' );
if( $equa =~ /^(<--|<==>|-->) (.+)/ ){
$arrow = $1;
$right = $2;
$left = $right;
$left =~ s/\@\S+/\@BOUNDARY/g;
}
elsif( $equa =~ /(.+) (<--|<==>|-->)$/ ){
$left = $1;
$arrow = $2;
$right = $left;
$right =~ s/\@\S+/\@BOUNDARY/g;
}
else{
die "Don't know how to fix bounadry reaction: $equa\n";
}
return "$left $arrow $right";
}
答案 0 :(得分:4)
正如已经解释的那样,if (/$pattern/)
表示if ($_ =~ /$pattern/
)。见General Variables in perlvar。然后问题是 - 您显示的代码中的$_
是什么?
Perl中的许多内置函数和运算符都使用$_
作为默认值。但据我所知,子例程不会使用$_
。 @_
获取参数,但它是一个完全不同的变量。
但是,在sub的内部,来自sub的封闭范围的$_
是可见的
use feature 'say';
sub show_it { say "I see: $_" }
for ('a'..'c') {
show_it(); # prints with a through c
}
如果这是在您显示的代码中,这意味着子检查变量'@BOUNDARY'
中的模式$_
- 但是从调用该子的范围。至少可以说这不是好的做法,并且很容易导致细微的错误。每当调用范围中的代码被更改时,必须检查sub,但我们不会通过sub的接口警告我们($_
不是参数)。此外,甚至不需要这个,因为调用代码可以检查和调整该调用。
我宁愿相信你所展示的是一个简单的错误,在这种情况下它应该是
return $equa if $equa =~ /\@BOUNDARY/;
这意味着sub首先检查输入是否已经存在,如果是,它只是返回它。显示的代码的其余部分支持这一点 - 它完全与'@BOUNDARY'
。
答案 1 :(得分:1)
对于那些没有进入奥术艺术的人来说,这是一种非常不直观的Perl-ism。
Perl有一个所谓的隐藏变量&#34;,$_
。本质上,任何带有单个参数的函数调用或这样的比较实际上都会取代$_
的值来代替缺失值。例如,
foo() if /bar/;
实际上相当于
if ($_ =~ /bar/) {
foo();
}
如果您将比较运算符视为函数调用,并且第一个示例具有我之前提到的缺失参数,那么这就很直观。
在您的情况下,如果$_
变量的值与相关正则表达式匹配,则代码正在执行的操作是返回某个变量的值。
答案 2 :(得分:1)
return $equa if /\@BOUNDARY/;
是
的缩写return $equa if $_ =~ /\@BOUNDARY/;
因此从if
语句修饰符转换为if
语句会导致
if (/\@BOUNDARY/) {
return $equa;
}
或
if ($_ =~ /\@BOUNDARY/) {
return $equa;
}
但是,您当前的代码很可能是错误的。它表明
return $equa if $equa =~ /\@BOUNDARY/;
应该使用,在这种情况下使用
完全没问题if ($equa =~ /\@BOUNDARY/) {
return $equa;
}