如何在运行时获取子程序的签名?
How do I get the signature of a subroutine in runtime?
Perl 通过 CORE::prototype
提供了 API,它允许您获得原型。 Sub::Util
进一步记录了这是使用 subs 的记录方法,
Returns the prototype of the given $code
reference, if it has one, as a string. This is the same as the CORE::prototype
operator; it is included here simply for symmetry and completeness with the other functions.
但是,我在任何地方都看不到有关如何在运行时获取 signatures 的信息? Perl 是否提供此功能?
来自 irc.freenode.net/#perl,
15:03 < Grinnz> there's no perl level api for that
这几乎是一个 perl 小高手。他向我指出了 this work from Nov 2019,它开始沿着“签名内省 API”的路径前进。“
目前这是不可能的,原因与传统参数解析 (my ($foo, $bar) = @_;
) 不可能的原因相同:它在子例程内部。
之前有人建议添加这样的东西,但目前看来不太可能。
这很...间接,但解析子并解析签名代码。
sub foo ($bar) { return 0 }
use B::Deparse;
$foo = B::Deparse->new->coderef2text(\&foo);
# contents of foo:
# BEGIN {${^WARNING_BITS} = "\x10\x01\x00\x00\x00\x50\x04\x00\x00\x00\x00\x00\x00\x55\x50\x55\x50\x51\x01"}
# use feature 'signatures';
# die sprintf("Too many arguments for subroutine at %s line %d.\n", (caller)[1, 2]) unless @_ <= 1;
# die sprintf("Too few arguments for subroutine at %s line %d.\n", (caller)[1, 2]) unless @_ >= 1;
# my $bar = $_[0];
# return 0;
@foo = split /\n/, $foo;
if ($foo[2] =~ /use feature 'signatures'/ &&
$foo[3] =~ /Too many arguments/ &&
$foo[4] =~ /Too few arguments/) {
@sig = ();
$n = 5;
do {
($sig) = $foo[$n] =~ /my (\W\w+) = /;
push @sig,$sig if $sig;
$n++;
} while ($sig);
print "Signature is (", join(",",@sig), ")\n";
}
Perl 通过 CORE::prototype
提供了 API,它允许您获得原型。 Sub::Util
进一步记录了这是使用 subs 的记录方法,
Returns the prototype of the given
$code
reference, if it has one, as a string. This is the same as theCORE::prototype
operator; it is included here simply for symmetry and completeness with the other functions.
但是,我在任何地方都看不到有关如何在运行时获取 signatures 的信息? Perl 是否提供此功能?
来自 irc.freenode.net/#perl,
15:03 < Grinnz> there's no perl level api for that
这几乎是一个 perl 小高手。他向我指出了 this work from Nov 2019,它开始沿着“签名内省 API”的路径前进。“
目前这是不可能的,原因与传统参数解析 (my ($foo, $bar) = @_;
) 不可能的原因相同:它在子例程内部。
之前有人建议添加这样的东西,但目前看来不太可能。
这很...间接,但解析子并解析签名代码。
sub foo ($bar) { return 0 }
use B::Deparse;
$foo = B::Deparse->new->coderef2text(\&foo);
# contents of foo:
# BEGIN {${^WARNING_BITS} = "\x10\x01\x00\x00\x00\x50\x04\x00\x00\x00\x00\x00\x00\x55\x50\x55\x50\x51\x01"}
# use feature 'signatures';
# die sprintf("Too many arguments for subroutine at %s line %d.\n", (caller)[1, 2]) unless @_ <= 1;
# die sprintf("Too few arguments for subroutine at %s line %d.\n", (caller)[1, 2]) unless @_ >= 1;
# my $bar = $_[0];
# return 0;
@foo = split /\n/, $foo;
if ($foo[2] =~ /use feature 'signatures'/ &&
$foo[3] =~ /Too many arguments/ &&
$foo[4] =~ /Too few arguments/) {
@sig = ();
$n = 5;
do {
($sig) = $foo[$n] =~ /my (\W\w+) = /;
push @sig,$sig if $sig;
$n++;
} while ($sig);
print "Signature is (", join(",",@sig), ")\n";
}