[Wellington-pm] The Perl Way: References & subroutines

Douglas Bagnall douglas at paradise.net.nz
Sun Feb 20 20:27:40 PST 2005


Quoting Kevin Dorne <sweetpea-perl at tentacle.net>:

>  I'm just not sure the best way 
>  to do this in Perl. 

You're not supposed to.
 
> my %nxt = fetch_next();
> sub fetch_next {
>  ...
>  my %msg = ( 'a' => 'b', ); 
>  return %msg;
> }

Here, in fetch_next, you are constructing a hash and throwing it away
again (which is generally ok). 

return %msg;

returns a list representation of %msg, and the assignment to %nxt 
turns the list into another hash. 

You might as well use an array, or simply a list:

return ( 'a' => 'b' );

the difference being that the list or array version retains the
order of pairs, which could conceivably be useful, but might make
fetch_next less readable.

> my $msg = fetch_next();
> sub fetch_next {
>  ...
>  my $msg = { 'a' => 'b', };
>  return $msg;
> }

This time you're only making one hash, which may save perl some
work, especially if is large.  Depending how you think, the
extra indirection and unitary nature of the reference might please or
confuse you.  If you're used to python for instance, do this.  On the
other hand, you loose the easy readability of the earlier example:
nobody knows that $msg is a hashref until they find and read fetch_next.

consider also 

sub fetch_next {
  my %msg = ( 'a' => 'b', ); #etc
  return \%msg;
}

you can save characters by building a plain hash and only making the 
reference to return. 

> my %msg;
> fetch_next(\%msg);
> sub fetch_next {
>  my $msg = shift;
>  ...
> }

that way you can have values already in %msg, and have fetch_next 
update it.  That can be useful, but if you're doing that though, 
it's not much more to make $msg an object, and go

$msg->fetch_next();

which might make the effect on $msg seem less like a side effect, and
make it harder for people to call fetch_next on the wrong things.  So,
it all depends.

cheers

Douglas Bagnall






More information about the Wellington-pm mailing list