perlmetaprogrammingsignaturesubroutinesubroutine-prototypes

How do I get the signature of a subroutine in runtime?


Perl provides an API via CORE::prototype, that allows you to get a prototype. This is further documented by Sub::Util which is the documented method for working with subs,

Sub::Util::prototype,

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.

However, I don't see anything anywhere on how to get the signatures in runtime? Does perl make this available?


Solution

  • This is very ... indirect, but deparse the sub and parse the signature code.

    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";
    }