2014-07-24 24 views
1

如果我有一个已经被定义为一个字符串变量,我应该保护赋给子程序的字符串吗?

my $x = "abc"; 
sub p { ... } 

我接下来要p("$x")或可以做p($x)p($hash->{x})

所有作品在我的测试。任何缺点不引用?

+0

做什么样的结果当你尝试上面提到的选项时,你会得到什么? – fugu

+0

所有作品在我的测试中。 –

+0

第三种情况应该不起作用,因为您没有在示例中定义'$ hash',但是不需要“保护”传递给子例程的字符串。 –

回答

8

不管它是否被用作子程序调用参数,它通常被认为是不好的做法,引用一个标量变量,如"$s",原因有二

  • 你是不必要的制作重复值的

  • 您可以调用一个重载字符串化行为

当然,第二个也可能是一个很好的理由选择做到这一点,因为你希望使用stringify特殊行为。

使用裸变量作为子例程参数的唯一缺点是,由于Perl通过引用传递值,因此可以从子例程内修改该值。但是,您需要修改@_的元素,这是非常难以做到的。

子程序的一般形式是这样的

sub proc { 
    my ($p1, $p2, $p3) = @_; 
    # Do stuff with $p1, $p1, $p3 
} 

中,你与参数的安全副本反正工作和修改的情况下他们不会对实际参数没有影响

8

p($x)p($hash->{x})都没问题。你已经把这些变量的副本,当你做

my ($x) = @_; 

my $x = shift; 

无需创建呼叫者的身边副本(使用"$x")了。


如果你没有复制的元素,你可以,如果你在子改变一个全局变量有一个问题,你也传递全局变量作为参数传递给子。

$ perl -E' 
    my $x; 
    sub f { $x = "def"; say $_[0] } 
    $x = "abc"; 
    say $x; 
    f($x); 
' 
abc 
def 

但是,你为什么要那样做?这样做的合理的情况是我能想到的是以下内容:

$ perl -E' 
    sub f { "def" =~ /(.*)/s; say $_[0] } 
    "abc" =~ /(.*)/s; 
    say $1; 
    f($1); 
' 
abc 
def 

所以也许f("$1")有道理的时候,但是仅此而已。