我想用来Devel::Declare注入多行Perl代码.但是,Devel::Declare::set_linestr()不能处理多行.
通常我会将多个语句一起作为一行加入.这些语句必须在单独的行上以保留其行号以用于错误报告目的.这是为了解决Method :: Signatures中的这个bug以及这个相关的bug.我愿意接受其他解决方案.
例如,Method :: Signatures目前会转换此代码......
use Method::Signatures;
func hello(
$who = "World",
$greeting = get_greeting($who)
) {
die "$greeting, $who";
}
Run Code Online (Sandbox Code Playgroud)
......进入这...
func \&hello; sub hello { BEGIN { Method::Signatures->inject_scope('') }; my $who = (@_ > 0) ? ($_[0]) : ( get_greeting($who)); my $greeting = (@_ > 1) ? ($_[1]) : ( "Hello"); Method::Signatures->too_many_args_error(2) if @_ > 2;
die "$greeting, $who";
}
Run Code Online (Sandbox Code Playgroud)
die $who 然后报告第4行而不是第7行.
我希望它是这个(或者可能涉及的东西#line).
func \&hello; sub hello { BEGIN { Method::Signatures->inject_scope('') };
my $who = (@_ > 0) ? ($_[0]) : ( "World");
my $greeting = (@_ > 1) ? ($_[1]) : ( get_greeting($who));
Method::Signatures->too_many_args_error(2) if @_ > 2;
die "$greeting, $who";
}
Run Code Online (Sandbox Code Playgroud)
这不仅忠实地再现了行号,而且如果get_greeting它从正确的行调用它将会报告.
根据您自己的回答,以下工作有效:
sub __empty() { '' }
sub parse_proto {
my $self = shift;
return q[print __LINE__."\n"; Foo::__empty(
);print __LINE__."\n"; Foo::__empty(
);print __LINE__."\n";];
}
Run Code Online (Sandbox Code Playgroud)
但会带来不可接受的开销,因为__empty()必须为每个参数调用该函数。__empty()通过使用永远不会计算为 true 的条件进行有条件调用,可以消除开销。
sub __empty() { '' }
sub parse_proto {
my $self = shift;
return q[print __LINE__."\n"; 0 and Foo::__empty(
);print __LINE__."\n"; 0 and Foo::__empty(
);print __LINE__."\n";];
}
Run Code Online (Sandbox Code Playgroud)