[aklug] Re: perl doesn't natively do booleans?????

From: Michael Fowler <michael@shoebox.net>
Date: Wed Aug 18 2010 - 10:48:38 AKDT

On Wed, Aug 18, 2010 at 01:37:54AM -0800, Arthur Corliss wrote:
>> Basically, never use prototypes. I can dig up links to describe in
>> detail what they're really for, but their uses are very specialized.
>
> I would alter that to say only use prototypes if you fully understand how
> Perl implements them.

As with most advice that includes 'never' or 'always', it's to be
ignored when you think you know better.

> They are very handy and I use them often, particularly because it
> (again) can help with consistency (accidentally leaving out an
> argument in a function call, for instance), or sometimes because, darn
> it, my sub just wants an array reference.

If you're using it to verify your subroutine is getting the proper
number of arguments, you're Doing it Wrong. Check @_ for that in the
code. Prototypes are not for validation; using them for it will
invariably trip someone up, either you, or someone using your code.

See http://shoebox.net/articles/perl-prototypes.txt

The quick summary is that prototypes are strictly for changing how code
is parsed. For example, an empty prototype allows for constants:

    sub BAR { 10 }
    sub FOO () { 10 }
    say BAR + 10; # prints 10, because BAR() got an argument of +10
    say FOO + 10; # prints 20, because FOO() takes no arguments

This also applies to functions that take arguments:

    sub afrob { $_[0] + 2 }
    sub bfrob ($) { $_[0] + 2 }
    say afrob 10, 11; # prints "1211", because afrob() takes one argument
    say bfrob 10, 11; # prints "12", because 11 was treated as an argument

You can also use it to take a reference automatically, but the problem
with doing so is that it's non-obvious in calling code.

    sub explicit { push @{ $_[0] }, "foo" }
    sub implicit (\@) { push @{ $_[0] }, "foo" }
    explicit(\@x);
    implicit(@x);

Both calls modify @x, but only the first call is it immediately obvious
that @x may be modified.

The one thing that prototypes are useful for is passing subroutines.

    sub block (&) { $_[0]->(10) }
    sub manual { $_[0]->(10) }
    block { $_[0] + 1 };
    manual sub { $_[0] + 1 };

Both calls do the same thing, but being able to omit the 'sub' improves
readability.

And that was the QUICK summary; there are so many ways prototypes can
trip a person up. They should only be used in extremely limited cases;
validation of the number and type of arguments is best done in the
subroutine itself.

Prototypes also do not work on methods. This makes it especially
frustrating trying to maintain code where the programmer thought they
do, but the prototype has long since stopped matching what arguments the
method is intended to receive. Trying to decipher if the prototype is
documentation, out of sync, or the method is ever called as a function
gets maddening.

> Actually, you've overlooked a corner case with inet_aton as well:
> inet_aton will take names in addition to string representations of IP
> addresses and attempt to resolve them via DNS. This may or may not be
> a desireable effect.

I didn't overlook it, I simply didn't mention it. Whether or not the
DNS lookup is relevant depends on what the input is.

--
Michael Fowler
www.shoebox.net
---------
To unsubscribe, send email to <aklug-request@aklug.org>
with 'unsubscribe' in the message body.
Received on Wed Aug 18 11:45:54 2010

This archive was generated by hypermail 2.1.8 : Wed Aug 18 2010 - 11:45:54 AKDT