2016-09-29 78 views
4

我使用的是一篇发表在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"; 
} 
+6

'返回$ EQUA如果/ \ @边界/;'是一样的'返回$ EQUA如果$ _ =〜/ \ @ BOUNDARY /;'有两个变量:$ equa和$ _ – toolic

+1

'/ $ pattern /'将匹配应用于当前保存在默认变量'$ _'中的任何内容。所以你提供的是不同的。例如,for(@arr)'在'$ _'中有数组元素,因为它迭代它们。这只是一个例子,'$ _'在Perl中使用很多。查看前面的代码,看看'$ _'中可以包含什么。 – zdim

+0

当您更改代码时,代码是否适用? – toolic

回答

4

如前所述,if (/$pattern/)表示if ($_ =~ /$pattern/)。请参阅General Variables in perlvar。那么问题是–你在代码中显示的$_是什么?

Perl中的许多内置运算符和运算符默认使用$_。但是子程序不会使用$_来做任何事情,据我所知。 @_获得参数,但它是一个完全不同的变量。

然而,子里面。如果这是为了在你展示的代码从子的封闭范围$_可见

use feature 'say'; 

sub show_it { say "I see: $_" } 

for ('a'..'c') { 
    show_it(); # prints with a through c 
} 

,这意味着在变量$_子检查模式'@BOUNDARY' –但是从调用子的范围。这至少可以说是不好的做法,并且很容易导致微妙的错误。任何时候调用范围中的代码发生变化时,都必须查看子集,但我们并未通过子接口警告($_不是参数)。此外,这甚至不需要,因为调用代码可以检查并调整通话。

我宁愿相信你展示的是一个简单的错误,在这种情况下,它应该是

return $equa if $equa =~ /\@BOUNDARY/; 

这意味着子首先检查输入是否有这个已经,如果它只是回报它。其余显示的代码支持这一点 - 这都是关于'@BOUNDARY'

1

这是一个Perl主义是为那些谁没有开始进入神秘的艺术非常直观。

Perl有一个所谓的“隐藏变量”,$_。实质上,任何带有单个参数或比较的函数调用实际上都会取代$_替代缺失值。例如,

foo() if /bar/; 

实际上相当于

if ($_ =~ /bar/) { 
    foo(); 
} 

这使得,如果你认为一个比较操作符是一个函数调用的直觉,以及第一例子具有我前面提到的缺少的参数。

就你的情况而言,如果$_变量的值与正在讨论的正则表达式的值相匹配,代码正在做的是返回某个变量的值。

+1

***隐藏变量***是错误的。 '$ _'等称为***特殊变量***或***预定义变量***。 – Borodin

+0

它被称为“默认变量”。 “隐藏变量”是一个很好的名字,我会开始使用它。 – Schwern

1
return $equa if /\@BOUNDARY/; 

是短期的

return $equa if $_ =~ /\@BOUNDARY/; 

所以从if语句修改器if语句结果转换在

if (/\@BOUNDARY/) { 
    return $equa; 
} 

if ($_ =~ /\@BOUNDARY/) { 
    return $equa; 
} 

但是,您的当前代码完全可能是错误的。它apears是

return $equa if $equa =~ /\@BOUNDARY/; 

应该被使用,在这种情况下,这是完全正常使用

if ($equa =~ /\@BOUNDARY/) { 
    return $equa; 
} 
相关问题