The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
$Id: HACKING,v 1.1 2005/03/24 18:04:52 chip Exp $

If you want to parse and understand a Perl6-style sub declaration,
but you don't want to actually filter the code, you can use some of
the guts of Perl6::Subs to do it.

HOWEVER, you should be aware that the interfaces described here are
NOT SUPPORTED, and this documention is provided in the spirit of
giving you enough rope to shoot yourself in the foot.

That said, here's the basic pattern:

    use Perl6::Subs ();    # note the () ... this means don't filter

    # find declaration text --
    #   everything up to (but not including) the '{' or ';'

    my $decl = 'method foo ($me: Int $a, Foo $f where { $f })';

    # instantiate Sub object from it

    my $sub = Perl6::Subs::Sub->new_from_decl($decl)
      or die "hey that's not a valid declaration";

At this point, $sub is a Sub object (Perl6::Subs::Sub).

(Note that the Sub object, as well as the below Param and Type
objects, were created with Class::Struct, so you can read up on
Class::Struct for usage details.)

Sub object attributes are:

  name       sub name (or undef if anonymous)
  traits     hash of subroutine traits
  p_inv      invocant Param object, e.g. $self (or undef)
  p_pos      array of positional Param objects
  p_pos_req  integer number of _required_ positional params
  p_named    hash of named Param objects
  p_slurpy   final slurpy Param object (or undef)

Param (Perl6::Subs::Param) object attributes include:

  name       e.g. '$self'
  type       Type object reference
  traits     hash of traits

Type object attributes include:

  name       type name, or undef for anonymous types
  base       base type, or undef
  where      "where" clause (only legal on anonymous types), or undef

NOTE ON TRAITS: Trait hash values may be undef, but this does not mean
the trait is missing!  Rather it means that the trait appeared without
parentheses.  Use $obj->has_trait($trait) to detect trait presence, or
use exists $object->traits->{$trait} if you want to type more.  :-)

NOTE ON SUBTYPES: Types may be named or anonymous (subtypes).  To find
a type name for an anonymous type, keep chasing the $type->base
reference until you find a named type.  There will be one.  So, for
example, to set $name to the name of type $type, use:

   my $t = $type;
   $t = $t->base until $t->name;
   my $name = $t->name;