Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

defining a HASH table by reference and using it in a sub function

by Buckaroo Buddha (Scribe)
on May 19, 2000 at 00:59 UTC ( #13118=perlquestion: print w/ replies, xml ) Need Help??
Buckaroo Buddha has asked for the wisdom of the Perl Monks concerning the following question:

How do I do this in one line?

sub build_list { ($RECORD,$RI,$RECORDxRI,$RECORDxRI_count_REF,$EACH_RECORD_REF) = @ +_; %RECORDxRI_count = %$RECORDxRI_count_REF; %EACH_RECORD = %$EACH_RECORD_REF; $RECORDxRI_count{$RECORDxRI}++; $EACH_RECORD{$RECORD} = ''; return(\%RECORDxRI_count,\%EACH_RECORD); } while <DATA> { @record = split('\t',$_); $RI = @record[38]; ($RECORD,$junk) = split('{',@record[54]); $RECORDxRI = $RECORD . ',' . $RI; ($RECORDxRI_count_REF,$EACH_RECORD_REF) = &build_list($RECORD,$RI, +$RECORDxRI,\%$RECORDxRI_count,\%EACH_RECORD); %RECORDxRI_count = %RECORDxRI_count_REF; %EACH_RECORD = %$EACH_RECORD_REF; # NOTE: I have to dereference both hashes # on every iteration of the while loop } # end while data
OK ... I understand that ONE line is a little overzealous, but I'm actually interested in making the function call to &build_list in one line...

Is there a way to get a full hash without dereferencing the hashes I pass to the routine on every iteration of this loop?

Could I get

to create that hash on its first pass and on subsequent iterations of "while" use the same hash?

Comment on defining a HASH table by reference and using it in a sub function
Select or Download Code
Replies are listed 'Best First'.
Re: defining a HASH table by reference and using it in a sub function
by btrott (Parson) on May 19, 2000 at 01:50 UTC

    Why don't you just always treat them as references? Then you won't have to reference/dereference them each time.

    # Define them as hash references. my $RECORDxRI_count_REF = {}; my $EACH_RECORD_REF = {}; while (<DATA>) { .... # Call build list--now you don't need to # take references to the hashes, because they're # already references build_list( $RECORD, $RI, $RECORDxRI, $RECORDxRI_count_REF, $EACH_ +RECORD_REF ); .... } sub build_list { my( $RECORD, $RI, $RECORDxRI, $RECORDxRI_count_REF, $EACH_RECORD_R +EF ) = @_; # These are hash references. To access them, # you *don't* need to assign them to hashes. # Just use the -> operator, which automatically # dereferences them. $RECORDxRI_count->{$RECORDxRI}++; $EACH_RECORD->{$RECORD} = ''; }
    Read perlref if this doesn't make sense.

Re: defining a HASH table by reference and using it in a sub function
by Russ (Deacon) on May 19, 2000 at 01:54 UTC

    I may be missing the point here...

    Since you seem to be using global variables anyway, you don't need to even return anything from build_list.

    You are passing in references to hashes. Those hashes are being modified by build_list. Your assignment to the hashes from the return value of build_list is redundant. They are already modified when build_list returns. Just use %RECORDxRI_count and %EACH_RECORD.

    I assume you are doing more in build_list and the <DATA> loop than you actually posted...

    Here is some condensed code (since you expressed interest in minimizing lines of code):

    my %RECORDxRI_count; my %EACH_RECORD; sub build_list { my( $RECORD, $RI, $RECORDxRI, $RECORDxRI_count_REF, $EACH_RECORD_REF + ) = @_; $RECORDxRI_count_REF->{$RECORDxRI}++; $EACH_RECORD_REF->{$RECORD} = ''; } while <DATA> { my( $Record54, $Record38 ) = (split /\t/)[54, 38]; my $RECORD = (split /{/, $Record54)[0]; $RECORDxRI = $RECORD . ',' . $Record38; build_list( $RECORD, $RI, $RECORDxRI, \%$RECORDxRI_count, \%EACH_REC +ORD ); }
    • I explicitly named the "global" variables, just for ease-of-maintenance.
    • $RI was always unused in build_list — I left it here because I suppose you are doing more than the posted code shows.
    • You had @ instead of $ when getting indices from @record. If you only want one value, don't use a slice.
    • I almost just defined the "global" hashes as references in the first place (to avoid the backslashes altogether).
      Update: See btrott's answer for more on this.
      my $RECORDxRI_count = {};
      my $EACH_RECORD     = {};

    Hope this is helpful...

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://13118]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2016-02-06 03:04 GMT
Find Nodes?
    Voting Booth?

    How many photographs, souvenirs, artworks, trophies or other decorative objects are displayed in your home?

    Results (215 votes), past polls