开发者

Pass hash and variable to subroutine

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;

}

I build a hash (开发者_开发问答%hash) and have another variable which I want to pass into a subroutine. However , inside the subroutine the way I am doing "my %hash = @_" also gets the value of $input2. What should I do to avoid this ?


The @_ is an array so set up your variables as such. If you want to address individual pieces you can address as $_[0]; Pass the hash by 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;

}


Either you pass first the variable, then the hash, or you pass a reference to the hash.


Perl flattens subroutine arguments into a single list--Perl automatically does a http://en.wikipedia.org/wiki/Apply to all non-prototyped subroutine calls. So, for the case of $self->check_something (%hash, message => $input2); the %hash is flattened.

So if:

%hash = ( foo => 1, bar => 2 );

Your sub call is:

   $self->check_something( foo => 1, bar => 2, message => $input2 );

So, if you want to pass your hash as a separate entity, you need to pass a reference:

   # 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 );

In most cases, you will probably want to do one of the first two examples I showed.

The benefit of the list flattening behavior is that is very easy to build up argument lists programatically. For example:

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 );
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜