\ shift不在eval字符串中工作

时间:2017-02-07 16:06:31

标签: perl

c = {key:[a.get(key,0),b.get(key,0)] for key in set(a)|set(b) if a.get(key,0) != b.get(key,0)} shift内的eval字符串中sub使用

示例1(使用eval):

grab_variable($variable1,$variable2,$variable3);
print $variable1.$variable2.$variable3; #should print: 123

sub grab_variable {
    my $number_of_parameters = @_;
    my $command1;
    my $command2;
    for (my $i = 1; $i <= $number_of_parameters; $i++) {
        $command1.= "\$RefVariable".$i." = \\shift;\n";
            #Generates string like:
                #$RefVariable1 = \shift;
                #$RefVariable2 = \shift;
                #...
    }
    eval $command1;
    for (my $i = 1; $i <= $number_of_parameters; $i++) {
        $command2.= "\$\{\$RefVariable".$i."\} = ".$i.";\n";
            #Generates string like:
                #${$RefVariable1} = 1;
                #${$RefVariable2} = 2;
                #...
    }
    eval $command2;
}

示例2(直接代码):

grab_variable($variable1,$variable2,$variable3);
print $variable1.$variable2.$variable3; #Prints: 123

sub grab_variable {
    $RefVariable1 = \shift;
    $RefVariable2 = \shift;
    $RefVariable3 = \shift;
    ${$RefVariable1} = 1;
    ${$RefVariable2} = 2;
    ${$RefVariable3} = 3;
}

示例1是动态的,可以解决我的真实(非简化)问题。如何在\shift代码字符串中使eval工作?

具体来说,我试图创建一个函数(子程序),它接受任意数量的变量(作为参数)并作为引用传递(而不是值) )因为它应该修改它们。

2 个答案:

答案 0 :(得分:3)

在潜艇中,shiftshift(@_)的缩写。

在潜艇之外,shiftshift(@ARGV)的缩写。

这适用于传递给eval EXPR的代码。

替换

$command1.= "\$RefVariable".$i." = \\shift;\n";

$command1.= "\$RefVariable".$i." = \\shift(\@_);\n";

您应始终使用use strict; use warnings qw( all );。你的代码会做你不应该做的所有事情,这样就可以解决这个问题。

我不确定你想要达到什么目标,但是你考虑过了吗

sub set_variables {
   for my $i (0..$#_) {
      $_[$i] = $i;        # Changing the elements of @_ changes them in the caller.
   }
}

set_variables(my ($var1, $var2, $var3));

say "$var1 $var2 $var3";

sub grab_variables { return \@_; }

my $ref_variables = grab_variables(my ($var1, $var2, $var3));

for my $i (0..$#$ref_variables) {
   $ref_variables->[$i] = $i;
}

say "$var1 $var2 $var3";

答案 1 :(得分:2)

Perl已经对子例程进行了别名传递,这比传递引用更简单。 @_的内容是子程序输入的别名;修改$_[$i]修改传递给子的第i个值。

sub grab_variables {
    for my $i (0 .. $#_) {
        $_[$i] = $i+1;
    }
}
my ($variable1,$variable2,$variable3);
grab_variable($variable1,$variable2,$variable3);
print $variable1.$variable2.$variable3;           #Prints: 123