1

目的是仅修改传递给函数的 hashref 参数,而不是修改原始 hashref。

{
    my $hr = { foo => q{bunnyfoofoo},
               bar => q{barbiebarbar} };

    foo( { %$hr, baz => q{bazkethound} } );
}

sub foo {
   my $args = shift // {};
}

我认为上述方法可行,但不确定是否有更好的方法(除了在通过之前修改原始参考)。

4

2 回答 2

1

无论您选择哪种语法,它仍然会归结为原始副本的浅层或深层(如果您需要修改内部函数)。

如果保证您的函数及其内部的所有内容都不会修改哈希,那么在调用之前分配此键并恢复先前的值或在调用后将其删除也足够了。

于 2012-08-07T15:12:54.820 回答
1

您的代码尽可能简单。您需要传递一个哈希并且您不想修改现有的哈希,因此您需要创建一个新的哈希。就是{ }这样。

潜在的问题是foo采用哈希引用而不是键值列表。

sub foo {
   my %args = @_;
   ...
}

你仍然可以做你之前所做的一切:

foo( foo => 'bunnyfoofoo', bar => 'barbiebarbar' );

my $hash = {
   foo => 'bunnyfoofoo',
   bar => 'barbiebarbar',
};
foo( %$hash, baz => 'bazkethound' );

有两个优点。

  1. 您不必到处使用{ }

  2. 您可以安全地修改参数。

    这是错误的:

    sub f {
       my $args = $_[0] // {};
       my $foo = delete($args->{foo});
       my $bar = delete($args->{bar});
       croak("Unrecognized args " . join(', ', keys(%$args)))
          if %$args;
       ...
    }
    

    还行吧:

    sub f {
       my %args = @_;
       my $foo = delete($args{foo});
       my $bar = delete($args{bar});
       croak("Unrecognized args " . join(', ', keys(%args)))
          if %args;
       ...
    }
    
于 2012-08-07T16:15:38.490 回答