Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

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.

Cheers,
Ovid

New address of my CGI Course.


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

Title:
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!
  • 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
  • Outside of code tags, you may need to use entities for some characters:
            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?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others musing on the Monastery: (8)
    As of 2014-09-18 23:59 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (128 votes), past polls