我有一个带有一组功能的模块,这些功能通过带有辅助函数的调度哈希实现:

my $functions = {
  'f1' => sub {
      my %args = @_;
      ## process data ...
      return $answer;
  },
[etc.]
};

sub do_function {
    my $fn = shift;
    return $functions->{$fn}(@_);
}


一些处理制表符分隔数据的脚本会使用此格式。被检查的列由适当的子例程转换。当处理列中的值时,我将数据的哈希传递给子对象,它生成标量,即该列的新值。

当前,这些子称为:

my $new_value = do_function( 'f1', data => $data, errs => $errs );


并且参数中的变量都声明为'my'-我的$ data,我的$ errs等。是否有可能在传递给subs的参数中更新其他值而不必返回它们?即不必这样做:

 ... in $functions->{f1}:
      my %args = @_;
      ## process data ...
      ## alter $args{errs}
      $args{errs}->{type_one_error}++;
      ## ...
      return { answer => $answer, errs => $args{errs} };
 ...

 ## call the function, get the response, update the errs
 my $return_data = do_function( 'f1', data => $data, errs => $errs );
 my $new_value = $return_data->{answer};
 $errs = $return_data->{errs}; ## this has been altered by sub 'f1'


我可以这样做:

  my $new_value = do_function( 'f1', data => $data, errs => $errs );
  ## no need to update $errs, it has been magically updated already!

最佳答案

您可以将引用传递给值,并在子例程中对其进行更新。

例如:

sub update {
    my ($ref_to_value) = @_;
    $$ref_to_value = "New message";
    return "Ok";
}

my $message = "Old message";

my $retval = update(\$message);

print "Return value: '$retval'\nMessage: '$message'\n";


从您的代码片段中可以看到,$errs已经引用了哈希。
因此,实际上,您要做的就是-注释掉$errs = $return_data->{errs};行并尝试

如果我的代码正确无误,则$errs将得到更新。然后,您应该将返回值更改为$answer并执行以下操作:

my $new_value = do_function( 'f1', data => $data, errs => $errs );

07-24 09:50