$VAR1 = '{';
$VAR2 = ' do {';
$VAR3 = ' package My::Package;';
$VAR4 = ' BEGIN {${^WARNING_BITS} = "\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x55\\x54\\x55\\x55\\x55\\x55\\x55\\x55"}';
$VAR5 = ' use strict;';
$VAR6 = ' use feature \'current_sub\', \'evalbytes\', \'fc\', \'say\', \'signatures\', \'state\', \'switch\', \'unicode_strings\', \'unicode_eval\';';
$VAR7 = ' die sprintf("Too few arguments for subroutine at %s line %d.\\n", (caller)[1, 2]) unless @_ >= 1;';
$VAR8 = ' my $class = $_[0];';
$VAR9 = ' my @args = @_[1 .. $#_]';
字符串 下面是我创建的一个快速替代方案,它似乎对我有效:
sub _get_signature ($called_sub) {
my $signature = q{};
if (
!eval {
require B::Deparse;
my ( $found_feature, $found_sig, @sig, @lines );
@lines = split( /\n/, B::Deparse->new->coderef2text( \&$called_sub ) );
foreach my $line (@lines) {
if ( $line =~ /\w*\};/ ) { # we've reach the end of the "do" block or similar
last;
}
if ( $line =~ /\w*use feature/ ) {
if ( $line =~ /signatures/ ) {
$found_feature = 1;
next;
}
last; # no signatures
}
if ( $found_feature && $line =~ /^\s*my (\W\w+) =/ ) {
push( @sig, $1 );
$found_sig = 1;
next;
}
if ($found_sig) {
last; # if we have started to find signatures and then stopped, we've reached the end of them.
}
}
if ($found_sig) {
$signature = join( q{, }, @sig );
}
1;
}
) {
croak("Unable to produce signatures due to $@");
}
return "($signature)";
}
4条答案
按热度按时间wnrlj8wa1#
这真是...间接的,但是反分析sub并解析签名代码。
字符串
d5vmydt92#
这在目前是不可能的,原因与传统的参数解析(
my ($foo, $bar) = @_;
)不可能的原因相同:它在子程序内部以前有人建议添加这样的东西,但目前似乎不太可能。
7rtdyuoh3#
从Perl 5.36开始(至少在我的环境中),mob's answer不再工作,因为有多个“前导行”:
字符串
下面是我创建的一个快速替代方案,它似乎对我有效:
型
smtd7mpg4#
来自irc.freenode.net/#perl,
字符串
这差不多就是perl的半老板了。他向我指出了this work from Nov 2019,它从“签名内省API”的路径开始。