my %hash;
my $input2 = "message";
#calling subroutine check_something
$self->check_something (%hash, message => $input2);
sub check_something {
my $self = shift;
my %p = @_;
my $message = $p{message};
my %hash = @_;
# do some action with the %hash and $input2;
}
我构建了一个哈希(%hash)并且有另一个我希望传递给子程序的变量。但是,在子程序中,我正在做的方式“我的%hash = @_”也获得了$ input2的值。我该怎么做才能避免这种情况?
答案 0 :(得分:5)
@_是一个数组,因此设置变量。如果你想要解决单个部分,你可以解决$ _ [0];通过ref传递哈希:
$self->check_something (\%hash, {message => $input2});
sub check_something {
my ($self, $ref, $message) = @_;
my %p = %{$ref};
# can reference the value of $input2 through $$message{'message'} or casting $message as a hash my %m = %{$message}; $m{'message'};
# do some action with the %hash and $input2;
}
答案 1 :(得分:1)
首先传递变量,然后传递散列,或者传递对散列的引用。
答案 2 :(得分:1)
将Perl flattens subroutine arguments放入单个列表中 - Perl自动对所有非原型子例程调用执行http://en.wikipedia.org/wiki/Apply。因此,对于$self->check_something (%hash, message => $input2);
的情况,%hash
被夷为平地。
所以如果:
%hash = ( foo => 1, bar => 2 );
您的子呼叫是:
$self->check_something( foo => 1, bar => 2, message => $input2 );
因此,如果要将哈希作为单独的实体传递,则需要传递引用:
# Reference to hash:
$self->check_something( \%hash, message => $input2 );
# To pass an anonymous copy:
$self->check_something( {%hash}, message => $input2 );
# To expand hash into an anonymous array:
$self->check_something( [%hash], message => $input2 );
在大多数情况下,您可能希望执行我展示的前两个示例之一。
列表展平行为的好处是以编程方式构建参数列表非常容易。例如:
my %args = (
foo => 'default',
bar => 'default_bar',
baz => 23,
);
$args{foo} = 'purple' if $thingy eq 'purple people eater';
my %result = get_more_args();
@args{ keys %result } = values %result;
my_amazing_sub_call( %args );