in reply to Optimizing the use of hashes in subroutines

I'm working on something very similar to what you described here. With the help of Limbic~Region, bart, castaway, and others, I've come up with something that seems to work for me. It looks like this (for fetching URLs):
my %pi; my ($status, $content, $type, $base, $length) = get_page(\$site, \%pi); print $pi{'length'}, " bytes\n"; #################################################### sub get_page { my ($site_ref, $pi) = @_; $browser = LWP::UserAgent->new() unless $browser; my $response = $browser->get($$site_ref); my $status = $response->status_line; my $content = $response->content; my $type = $response->content_type; my $base = $response->base; my $length = commify(length($content)); if (!$response->is_success) { die "\nError: $status ($site)\n"; } @{$pi}{qw(status content type base length)} = ($status, $content, $type, $base, $length); }

It may not be the most-efficient, because I'm still trying to wrap my head around references and anonymous references to subs, but it does work for me.

Comments or improvements are welcome, as long as they provide the fishing pole and a lure, not a basket of fish..

Replies are listed 'Best First'.
Re: Re: Optimizing the use of hashes in subroutines
by Anonymous Monk on May 26, 2003 at 16:37 UTC

    If you'll excuse me saying this (which you won't) but somebody is taking the p*** outta you, if this is what they showed you to do (which they probably didn't).

    You call a sub, passing in a hashref \%pi.

    In the sub, you assign a bunch of values to local disrete scalars.

    You then assign these scalars to a hash, using a hash slice.

    You then extract the values from the hash (via the hash slice), and return them as a list.

    The calling code then assign the list to another bunch of discrete scalars which you then ignore and access the values via the hash?

    This isn't just inefficient, it's {expletive}.

    And what do you achieve by passing \$site, just so you can do $$site_ref? Your passing one scalar instead of another and dereferencing it twice. Totally useless use of a references.

    Here are four different ways of doing what your doing, each of which is simpler, clearer and more efficient. Try and understand how they each work, and then pick one.

    No hash

    my ($status, $content, $type, $base, $length) = get_page($site); print $length, " bytes\n"; #################################################### sub get_page { my ($site, $pi) = @_; $browser = LWP::UserAgent->new() unless $browser; my $response = $browser->get($site); my $status = $response->status_line; my $content = $response->content; my $type = $response->content_type; my $base = $response->base; my $length = commify(length($content)); if (!$response->is_success) { die "\nError: $status ($site)\n"; } return $status, $content, $type, $base, $length; }

    Assign to a hash slice in the calling code from the returned the list.

    my %pi; @%pi{qw(status content type base length)) = get_page($site); print $length, " bytes\n"; #################################################### sub get_page { my ($site) = @_; $browser = LWP::UserAgent->new() unless $browser; my $response = $browser->get($site); if (!$response->is_success) { die "\nError: $status ($site)\n"; } return $response->status_line, $response->content, $response->content_type, $response->base, commify(length($content)); }

    Assign direct to the hash. No lists.

    my %pi; get_page($site, \%pi); print $pi{'length'}, " bytes\n"; #################################################### sub get_page { my ($site, $pi) = @_; $browser = LWP::UserAgent->new() unless $browser; my $response = $browser->get($site); $pi->{status} = $response->status_line; $pi->{content} = $response->content; $pi->{type} = $response->content_type; $pi->{base} = $response->base; $pi->{length} = commify(length($pi->{content})); if (!$response->is_success) { die "\nError: $status ($site)\n"; } }

    Assign to hash slice direct. Don't return a list

    my %pi; get_page($site, \%pi); print $pi{'length'}, " bytes\n"; #################################################### sub get_page { my ($site, $pi) = @_; $browser = LWP::UserAgent->new() unless $browser; my $response = $browser->get($site); if (!$response->is_success) { die "\nError: $status ($site)\n"; } my $content = $response->content; @{$pi}{qw(status content type base length)} = ( $response->status_line; $content; $response->content_type; $response->base; commify(length($content)); ); return; }