Sub-Signatures

 view release on metacpan or  search on metacpan

lib/Sub/Signatures.pm  view on Meta::CPAN

is whether or not a given argument is capable of providing what we need, not
whether or not it's a given type.  This puts your author in a bind.  Objects
which are unrelated by inheritance but present the same behaviors are known as
I<allomorphic>.  

Allomorphism, despite the funny name, is something Perl programmers use all the
time without being aware of what it's called.  However, to add allomorphism
support to this module would complicate it quite a bit.  Thus, to keep things
as simple as possible, we restrict ourselves to dispatching on the number of
arguments.  Thus, you, the programmer, will still need to validate the
different types and/or capabilities of the arguments you pass in.

If you prefer, you can still list the data type before the argument:

  sub foo (ARRAY $bar) {...}

However, the C<ARRAY> will be discarded.  Think of it as documentation.

=head1 BUGS AND LIMITATIONS

For the most part this module I<just works>.  If you are having problems,
consult this list to see if it's covered here.

=over 4

=item * "sub foo {}"

Due to limitations with parsing Perl, this module does I<not> attempt to take
advantage of C<Filter::Simple>'s "FILTER_ONLY" functionality.  This means that
this module is a straightforward filter.  As a result, if you have text in
quoted areas which resembles "signified" subroutines, you may see strange
results.  Fortunately, this is very rare.

=item * Do not mix "signatured" subs with "non-signatured" of the same name

In other words, don't do this:

 sub foo($bar) { ... }
 sub foo { ... }

If you want something like that, name a L<Fallback> subroutine:

 sub foo($bar) { ... }
 sub foo(fallback) { ... }

However, you don't need signatures on all subs.  This is OK:

 sub foo($bar) { ... }
 sub baz { ... }

=item * Use caution when mixing functions and methods

Internally, functions and methods are handled quite differently.  If you use
this with a class, you probably do not want to use signatures with functions in
said class.  Things will usually work, but not always.  Error messages will be
misleading.

  package Foo;
  use Sub::Signatures qw/methods/;

  sub new($class) { bless {} => $class }

  sub _some_func($bar) { return scalar reverse $bar }

  sub some_method($self, $bar) { 
      $self->{bar} = _some_func($bar);
  }

  sub some_other_method($self, $bar, $baz) {
      # this fails with 
      # Could not find a method matching your signature: _some_func(SCALAR) at ...
      $self->{bar} = _some_func($bar, $baz);
  }

  1;

=item * One package per file.

Currently we cannot handle more than one package per file with this module.
It sometimes works with methods, but there are no guarantees.  When we can
parse Perl reliably, this may change :)

=item * Can only handle scalars and references in the arg list.

At the present time, the only variables allowed in signatures are those
that begin with a dollar sign:

 sub foo($bar, $baz) {...}; # good
 sub foo($bar, @baz) {...}; # not good

=item * Handle prototypes correctly

Don't try using prototypes with this module.  It currently tends to get caught
in an infinite loop if you do that, so don't do that.

 use Sub::Signatures;

 sub foo($$) {...} # don't do that

See C<t/90prototypes.t> and the code at the end if you want to fix this.

Of course, prototypes in Perl are widely considered to be broken anyway, so why
use them?

=back

=head1 HOW THIS WORKS

In a nutshell, each subroutine is renamed with a unique, signature-based name
and a sub with its original name figures out how to dispatch to it.  It loosely
works like this:

 package Some::Package;

 sub foo($bar) {
     return [$bar];
 }
 
 sub foo($bar, $baz) {
     return exists $baz->{$bar};
 }

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.419 second using v1.00-cache-2.02-grep-82fe00e-cpan-9e6bc14194b )