develooper Front page | perl.perl5.porters | Postings from November 2016

RFC: core sub signature introspection

Thread Next
From:
Aaron Crane
Date:
November 13, 2016 13:53
Subject:
RFC: core sub signature introspection
Message ID:
CACmk_tvUuuiA-b12o05-bwQwBjSV5s-VyQCMJRdqAAJjbYapBw@mail.gmail.com
I've just pushed a branch arc/smoke-me/signature-introspection,
containing an initial implementation of introspection for core
subroutine signatures.

I've decided that the API visible to pure Perl code, at least for now,
should consist of a set of new functions, each of which returns a
single piece of information. I considered and rejected two other
options. First, I considered returning a hash ref containing all the
available information; I rejected that for forward-compatibility
reasons: future changes to core signatures may make it hard and/or
undesirable to extract any given piece of information we currently
provide. Second, I considered returning an opaque object whose methods
return individual pieces of information; I rejected that because,
AFAIK, there are currently no other core APIs that return instances.

The API consists of three new functions in the Internals:: namespace,
each of which takes a coderef as an argument:

* cv_min_arity($coderef) - returns the minimum number of arguments
accepted by $coderef. If the coderef has no signature, it returns 0.

* cv_max_arity($coderef) - returns the maximum number of arguments
accepted by $coderef. If the coderef has no signature, or it ends in a
slurpy argument, it returns a numeric infinity (0+'Inf')

* cv_slurpy($coderef) - returns a string indicating the nature of the
trailing slurpy argument for $coderef. If the coderef has a signature
but no slurpy argument, it returns Perl's canonical false value. If
the coderef has a signature with a slurpy hash argument, it returns a
string containing '%'. Otherwise (no signature, or a signature with a
slurpy array argument), it returns a string containing '@'.

Example:

use experimental 'signatures';
sub foo ($x, $y = 17, %h) {}
say for Internals::cv_min_arity(\&foo),
    Internals::cv_max_arity(\&foo),
    Internals::cv_slurpy(\&foo);
# prints: 0 Inf %

Comments are greatly welcomed on both the design and the
implementation. In particuar, I suspect that Internals:: is the wrong
place for these functions to live in the long term, but it seemed like
a reasonable straw-man location. Also, there isn't yet any
documentation; I'm delaying doing that until there's consensus on the
design.

Thanks once again to Dave for the work he's done on signatures; I was
pleasantly surprised at how easy it was to get at the information I
needed.

-- 
Aaron Crane ** http://aaroncrane.co.uk/

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About