我正在重构一些应用程序代码,我希望能够从子例程中删除一些参数。例如,假设我有以下[1]:
sub do_something {
my ( $param1, $param2, $param3, $param4 ) = ( @_ );
....
}
然而,作为重构的一部分,我使参数2和3变得多余。更新此方法签名是一个简单的部分,但有一种直接更新所有调用的方法吗?
我一直在做一些定制的grep / sed / perl来做这件事,但是对sub的一些调用是多行的,这使得它很痛苦,每次我在一个项目上这样做这是定制的。是否有适合进行此特定重构的工具?
[1] - 不是实际的参数或子程序名称,我向你保证!
答案 0 :(得分:3)
Padre有一些重构功能,但我不知道它是否能达到你想要的效果。
将您的界面更改为接受哈希而不是位置列表,这将使未来的更改比现在更少。
sub do_something {
my (%param) = (@_);
...
}
do_something(foo => 23, bar => 42);
答案 1 :(得分:0)
如果您的测试套件具有接近100%的代码覆盖率,您可以使用它来查找所有呼叫站点。
给出callstack中位置的参数,caller
内置函数返回
我们现在可以添加一些记录调用位置的代码。我们可以将结果放入某些数据结构中进行自动处理,也可以将报告写入日志文件。 E.g。
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
(文件名-
表示STDIN)
因此,给定一个合适的测试套件,可以找到无法获取的呼叫站点。
如果您有非moronic编辑器,您还可以发出一个脚本,依次打开每个文件并将光标定位在正确的行上:
say "kate -l $line $file";
say "vim +$line $file";