重构perl子例程的参数列表
我目前正在重构一些应用程序代码,希望能够从子例程中删除一些参数。例如,假设我有以下[1]:重构perl子例程的参数列表,perl,refactoring,Perl,Refactoring,我目前正在重构一些应用程序代码,希望能够从子例程中删除一些参数。例如,假设我有以下[1]: sub do_something { my ( $param1, $param2, $param3, $param4 ) = ( @_ ); .... } 然而,作为重构的一部分,我将参数2和3设置为冗余的。更新这个方法签名很容易,但是有没有一种简单的方法来更新对它的所有调用 我一直在做一些定制的grep/sed/perl来做这件事,但是对sub的一些调用是通过多行进行的,这让我很痛苦,
sub do_something {
my ( $param1, $param2, $param3, $param4 ) = ( @_ );
....
}
然而,作为重构的一部分,我将参数2和3设置为冗余的。更新这个方法签名很容易,但是有没有一种简单的方法来更新对它的所有调用
我一直在做一些定制的grep/sed/perl来做这件事,但是对sub的一些调用是通过多行进行的,这让我很痛苦,每次我在一个项目上做这件事都是定制的。有没有适合进行这种特定重构的工具
[1] -我向您保证,不是实际的参数或子例程名称 有一些重构功能,但我不知道它是否能实现您想要的
将接口更改为接受哈希而不是位置列表,这将使将来的更改比现在少
sub do_something {
my (%param) = (@_);
...
}
do_something(foo => 23, bar => 42);
如果您有一个代码覆盖率接近100%的测试套件,您可以使用它来查找所有调用站点 给定调用堆栈中位置的参数,
调用方
内置返回
sub this_logs {
{
# seperate scope to not pollute your sub
state $log_fh //= do {
open my $fh, ">", "record_callsites.log"; # assuming autodie;
$fh;
};
state $seen = {};
my (undef, undef, undef, $sub) = caller(1);
my ($package, $file, $line, ) = caller(0);
my $site = $sub ? "$sub()" : "pkg $package";
unless ($seen->{$file}{$line}++) {
say {$log_fh} "CALL from $site at $file line $line";
}
}
my ($param1, $param2) = @_;
# etc
}
假设你所有的代码都是
this_logs(1, 2, 3); # direct call
foo(); # call from same package
my $sub = "this_" . "logs";
baz($sub); # call by name
Foo::bar(); # call from different package
foo(); # duplicate call
sub foo {
return this_logs(5, 6, 7);
}
sub baz {
shift()->(1, 2, 3); # no strict refs for this, please
};
package Foo;
sub bar {
main::this_logs();
}
这将生成日志文件
CALL from pkg main at - line 20
CALL from main::foo() at - line 28
CALL from main::baz() at - line 31
CALL from Foo::bar() at - line 3
(文件名-
表示标准输入)
因此,如果有一个合适的测试套件,它就能够找到无法使用grep的呼叫站点
如果您有一个非傻瓜编辑器,您还可以发出一个脚本,依次打开每个文件并将光标定位在正确的行上:
say "kate -l $line $file";
say "vim +$line $file";
我不知道有任何快捷方式,但您是否难以可靠地找到方法中的调用,或者编辑它们以符合新接口的要求?找到它们很容易。所有实例都在一个包中,可以使用grep找到。编辑才是问题所在。我可以编写一些脚本来分解调用参数列表并将其重新组合起来,但这可能是定制的。也许是时候给我自己写一个重构模块了。你说调用有时会分散在多行上,所以我假设生成这些参数需要进行非平凡的计算。因此,我认为手动清理许多调用站点是必要的,因为仅仅删除参数可能只会删除一些提到的计算。例如,在通话前可能会有多余的线路,在通话前肯定会有多余的线路。我的计划是删除参数,然后使用git diff的奇迹来检查哪些变量现在是冗余的,并删除这些变量。对参数使用哈希似乎有点错误(不确定为什么,可能只是因为我目前没有这么做!),但我认为,一旦一个子程序有多个参数,这可能是一种方法。我也会好好教训教士的。你不应该有那种感觉。这是一个。啊哈!另一本书要添加到我的购买清单中。谢谢我想补充一点,以这种方式使用散列并不能免除您对参数的详细处理,包括清理方法的非必要输入。根据经验,我可以告诉您,在几乎没有验证的情况下上下传递散列引用(例如,
%param
随处可见)的Perl代码堆栈可能会花费大量时间来维护和调试。不过,如果您能很好地命名这些键,daxim在这里的回答将帮助您找到冗余参数的传入位置。有趣的是,这是测试套件内部的一个函数,所以我希望它有100%的覆盖率!这看起来非常有用。我会尽快给它试运行。