在子程序中引用@_的元素以避免重复代码是否安全?我也想知道以下是好的做法还是可以简化.我有一个子程序mod_str,它接受一个选项,说明是否应该就地修改字符串参数:
- use feature qw(say);
- use strict;
- use warnings;
- my $str = 'abc';
- my $mstr = mod_str( $str,in_place => 0 );
- say $mstr;
- mod_str( $str,in_place => 1 );
- say $str;
- sub mod_str {
- my %opt;
- %opt = @_[1..$#_];
- if ( $opt{in_place} ) {
- $_[0] =~ s/a/A/g;
- # .. do more stuff with $_[0]
- return;
- }
- else {
- my $str = $_[0];
- $str =~ s/a/A/g;
- # .. do more stuff with $str
- return $str;
- }
- }
为了避免在上面的if和else块中重复/复制代码,我尝试改进mod_str:
- sub mod_str {
- my %opt;
- %opt = @_[1..$#_];
- my $ref;
- my $str;
- if ( $opt{in_place} ) {
- $ref = \$_[0];
- }
- else {
- $str = $_[0]; # make copy
- $ref = \$str;
- }
- $$ref =~ s/a/A/g;
- # .. do more stuff with $$ref
- $opt{in_place} ? return : return $$ref;
- }
解决方法
“就地”标志将函数的接口更改为应该是新函数的点.它将简化界面,测试,文档和内部功能,以实现两个功能.用户已经为您做出了这样的选择,而不是必须解析参数并拥有一个大的if / else块.
查看它的另一种方法是将in_place选项始终设置为常量.因为它从根本上改变了函数的行为方式,所以没有明智的情况你会写in_place => $标志.
一旦你这样做,重用变得更加明显.编写一个函数来执行操作.写另一个在副本上调用它.
- sub mod_str_in_place {
- # ...Do work on $_[0]...
- return;
- }
- sub mod_str {
- my $str = $_[0]; # string is copied
- mod_str_in_place($str);
- return $str;
- }