Perl:修改作为param传递给子例程的变量

时间:2014-10-16 22:17:56

标签: perl parameters pass-by-reference subroutine

我需要在例程中修改变量,因此它在离开例程后保留更改。这是一个例子:

$text = "hello";
&convert_to_uppercase($text);
print $text;

我想在屏幕上看到“HELLO”,而不是“你好”。

例程如下:

sub convert_to_uppercase($text){
  <something like $text = uc($text);>
}

我知道如何在PHP中执行此操作,但似乎参数不会以相同的方式更改。而且,我一直在寻找各地,我找不到具体的答案。

我会感激任何帮助。谢谢!

2 个答案:

答案 0 :(得分:5)

在调用Perl子例程时,你 不应该使用&符号&。仅在将代码视为数据项时才需要,例如在获取引用时,例如\&convert_to_uppercase。从Perl 5的第4版开始,在电话中使用它并不是必需的,它会做一些你可能不想要的神秘事物。

子程序修改参数是很常见的,但@_的元素是实际参数的别名,所以你可以通过修改那个数组来做你想要的。

如果你写这样的子程序

sub convert_to_uppercase {
    $_[0] = uc $_[0];
}
然后它会按你的要求做。但通常最好返回修改后的值,以便调用代码可以决定是否覆盖原始值。例如,如果我有

sub upper_case {
    uc shift;
}

然后可以将称为作为

my $text = "hello"; 
$text = upper_case($text);
print $text;

根据需要执行,并修改$text;或者作为

my $text = "hello";
print upper_case($text);

使$text保持不变,但返回更改后的值。

答案 1 :(得分:3)

传递一个引用并修改子程序中的原始变量将如下所示:

$text = 'hello';
convert_to_uppercase(\$text);  #notice the \ before $text
print $text;

sub convert_to_uppercase {       #perl doesn't specify arguments here

    ### arguments will be in @_, so @_ is now a list like ('hello') 
    my $ref = shift;             #$ref is NOT 'hello'. it's '$text'

    ### add some output so you can see what's going on:
    print 'Variable $ref is: ', $ref, " \n";  #will print some hex number like SCALAR(0xad1d2)
    print 'Variable ${$ref} is: ', ${$ref}, " \n"; #will print 'hello'

    # Now do what this function is supposed to do:
    ${$ref} = uc ${$ref};  #it's modifying the original variable, not a copy of it
}

另一种方法是在子程序中创建一个返回值并修改子程序之外的变量:

$text = 'hello';
$text = convert_to_uppercase($text);  #there's no \ this time
print $text;

sub convert_to_uppercase {
    # @_ contains 'hello'
    my $input = shift;    #$input is 'hello'
    return uc $input;    #returns 'HELLO'
}

但是convert_to_uppercase例程似乎是多余的,因为这就是uc所做的。跳过所有这些,然后执行此操作:

$text = 'hello';
$text = uc $text;