Perl:将哈希引用加上额外的键/值作为一个哈希引用传递的正确方法是什么?

时间:2012-08-07 15:06:55

标签: perl hash arguments parameter-passing hashref

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

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

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

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

我认为上述方法可行,但我不确定是否有更好的方法(除了在传递前修改原始引用)。

2 个答案:

答案 0 :(得分:1)

无论你选择什么语法,它仍然可以归结为浅或深(如果你需要修改内部功能)原件的副本。

如果您的函数及其中的所有内容都保证不会修改散列,那么在调用之前分配此密钥并恢复之前的值或在调用之后删除它也是足够的。

答案 1 :(得分: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;
       ...
    }