我有一个带有一组功能的模块,这些功能通过带有辅助函数的调度哈希实现:
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 );