Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

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

&build_list(\%hash1,\%hash2);
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 ); }
    Notes:
    • 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.
      Like:
      my $RECORDxRI_count = {};
      my $EACH_RECORD     = {};

    Hope this is helpful...
    Russ

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2015-08-01 02:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (285 votes), past polls