Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

If you're familiar with modern programming languages other than Perl, you may be frustrated with Perl's relatively simple argument handling. While it's very easy to understand, it leads to a wide variety of bugs that are far less common in other languages. Consider the following example of overloading a method to be both a setter and a getter (a common idiom in Perl):

sub name { my $self = shift; if (@_) { $self->{name} = shift; return $self; } return $self->{name}; }

The intent is to allow the programmer to do this:

$person->name; # get the name $person->name("Ovid"); # set the name

Superficially, this looks fine. However, this code throws away information about the arguments which in turn leads to more bugs. What happens when the person using this code tries the following:

$person->name(qw/Publius Ovidius Naso/); # or $person->name([qw/Publius Ovidius Naso/]); # or my $name = Name->new("Publius Ovidius Naso"); $person->name($name);

With the code as written, all of those method calls would "succeed" and silently DWIDM (do what I don't mean.) This is a pernicious source of bugs. In fact, there's a lot of debate in the Perl community about whether or not it's worth putting in a lot of extra checks in the code to protect against this.

sub name { my $self = shift; if (1 == @_ && ! ref $_[0]) { $self->{name} = shift; return $self; } elsif (! @_) { return $self->{name}; } else { croak "Unknown arguments to name()"; } }

Wow. Our nice, clean, easy to read subroutine is starting to turn into an ugly mess. That's one of the reasons I've favored separate setters and getters, but what I would really like to do is this (available in just about any modern programming language):

sub name($self) { return $self->{name}; } sub name($self, $name) { $self->{name} = $name; return $self; }

Wouldn't that be nice? It would be so much easier to program that way. Well, now you can. I've uploaded Sub::Signatures to the CPAN.

It allows you to specify method and function signatures and dispatch accordingly. In 'loose' mode (the default), it merely dispatches based on the number of arguments:

use Sub::Signatures; sub foo($bar) { print $bar; } sub foo($bar, $baz) { print "$baz, $bar"; } foo(1); # prints 1 foo(1,2); # prints 1, 2 foo(1,2,3); # fatal error

In 'strict' mode, it requires that functions/methods be "typed" according to what ref would return. If ref returns nothing, then SCALAR is assumed. If not type is specified, SCALAR is assumed. That, by the way, is why the &name examples above do what I meant. In strict mode, with no type specified, the $name argument is required to be a SCALAR. Attempting to assign a Name object is a fatal error.

Currently supported features:

  • Methods
  • Subroutines
  • Optional strong typing via the ref function
  • Exporting
  • Inheritance
  • Useful error message

And in version 0.1, currently on its way to the CPAN, I've added support for anonymous functions and halting compilation for duplicate signatures.

Yes, this is alpha code and yes, it's a source filter. If your particular brand of dogmatism says "no source filters" that's fine, but do read this first. If you still don't want to use this, I won't be offended.

If you do want this, please give me feedback, suggestions, bug reports, etc. I would like to get this "production ready" if possible.


New address of my CGI Course.

In reply to Use method/function signatures with Perl by Ovid

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others making s'mores by the fire in the courtyard of the Monastery: (7)
    As of 2018-07-17 02:41 GMT
    Find Nodes?
      Voting Booth?
      It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

      Results (353 votes). Check out past polls.