将哈希和变量传递给子例程

时间:2011-07-29 18:45:23

标签: perl

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的值。我该怎么做才能避免这种情况?

3 个答案:

答案 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 );