Perl - 参数传递函数作为函数参数 - 漂亮而清晰的方式

时间:2014-09-11 12:41:52

标签: perl function arguments

你好我有使用hash传递参数的函数,这样:

&group_AoA_to_HoA_by_AoAs_columns({
    AoA          => \@group_file_by_line_numbers_AoA,
    HoA          => \%group_file_by_group_names_HoA,
    key_index    => 0,
    columns      => "ALL",
    save_method  => \&append_or_overwrite,
    action       => "ADD"
});

在这个函数中,我以这种方式访问​​传递的变量:

my $AoA         = $args->{"AoA"};
my $HoA         = $args->{"HoA"};
my $key_index   = $args->{"key_index"};
my $columns     = $args->{"columns"};
my $save_method = $args->{"save_method"};
my $action      = $args->{"action"};

参数"save_method"是另一个函数的名称(作为参数传递给group_AoA_to_HoA_by_AoAs_columns函数)。此函数也被称为(来自group_AoA_to_HoA_by_AoAs_columns函数),带有一些传递的参数:

$save_method->({
    action     => $action,
    position   => \$HoA->{ $array->[$key_index] },
    data       => [@selected_columns],
});

参数"action"第一次传递给"group_AoA_to_HoA_by_AoAs_columns"函数,第二次传递给"save_method"所指的函数。这个论点没有其他原因。

所以最后我的问题是,是否有可能将此代码重写为更加统一的等价,从中可以立即明确"action"参数仅由"save_method"所指的函数使用?这样的事情会很好:

&group_AoA_to_HoA_by_AoAs_columns({
    AoA          => \@group_file_by_line_numbers_AoA,
    HoA          => \%group_file_by_group_names_HoA,
    key_index    => 0,
    columns      => "ALL",
    save_method  => \&append_or_overwrite({
                          action       => "ADD"
    })
});

2 个答案:

答案 0 :(得分:4)

如果您希望使用指定参数

调用append_or_overwrite,则可以使用匿名函数
save_method  => sub {
  # 'return' is optional
  return append_or_overwrite({
                      action       => "ADD"
  })
}

答案 1 :(得分:3)

一个选项是在提供任何静态参数的匿名子例程中包含对save方法的引用:

save_method => sub { append_or_overwrite({ action => 'ADD', %{shift()}}) },

%{shift()}允许您使用当前执行的相同pass-a-hashref约定来指定任何其他参数:

$save_method->({
    position => \$HoA->{ $array->[$key_index] },
    data     => [@selected_columns],
});

另一种方法是使用数组引用指定save方法,其中第一个值是CODE引用,任何其他值都是它的参数。

save_method => [\&append_or_overwrite, action => 'ADD'],

将其调用为:

my ($code, @args) = @$save_method;
$code->({
    position => \$HoA->{ $array->[$key_index] },
    data     => [@selected_columns],
    @args,
});

Tangent:将保存方法数据传递为[@selected_columns]会创建(浅)副本。如果您不需要副本(因为保存方法不会对其进行修改),最好编写\@selected_columns以传递对原始数组的引用。同样,我不确定您为何通过\$HoA->{ $array->[$key_index] }传递位置,这似乎是对数组引用的引用,而不是直接将数组引用传递给$HoA->{ $array->[$key_index] }