Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Can a hash self reference?

by tcf03 (Deacon)
on Jul 01, 2005 at 15:25 UTC ( #471751=perlquestion: print w/ replies, xml ) Need Help??
tcf03 has asked for the wisdom of the Perl Monks concerning the following question:

What Im trying to do is easiest explained by some sample code
#!/usr/bin/perl -w use strict; use diagnostics; my %hash; %hash = ( 1 => { ONE => "testdir", TWO => "tmpdir" }, 2 => { LOCATIONA => "$hash{1}{ONE}/$hash{1}{TWO}/my_file.txt +", LOCATIONB => "$hash{1}{TWO}/$hash{1}{ONE}/my_file.txt +" } ); print "$hash{2}{LOCATIONA} = location a\n"; print "$hash{2}{LOCATIONB} = location b\n";
The output I get is this
Use of uninitialized value in concatenation (.) or string at test2 lin +e 7 (#1) (W uninitialized) An undefined value was used as if it were alread +y defined. It was interpreted as a "" or a 0, but maybe it was a mi +stake. To suppress this warning assign a defined value to your variables. To help you figure out what was undefined, perl tells you what ope +ration you used the undefined value in. Note, however, that perl optimiz +es your program and the operation displayed in the warning may not necessa +rily appear literally in your program. For example, "that $foo" is usually optimized into "that " . $foo, and the warning will refer +to the concatenation (.) operator, even though there is no . in your program. //my_file.txt = location a //my_file.txt = location b
Is there a way to do this within a hash?

Ted
--
"That which we persist in doing becomes easier, not that the task itself has become easier, but that our ability to perform it has improved."
  --Ralph Waldo Emerson

Comment on Can a hash self reference?
Select or Download Code
Re: Can a hash self reference?
by coke (Acolyte) on Jul 01, 2005 at 15:33 UTC
    Your problem, I think, is that you're trying to do this all at once - at the time you ask for the self-referencing portion, it's not actually been stored in the hash yet. You need to break this up into smaller chunks, so that the values you want are defined by the time you ask for them:
    my %hash; $hash{1}{ONE} = "testdir"; $hash{1}{TWO} = "tmpdir"; $hash{2}{LOCATIONA} = "$hash{1}{ONE}/$hash{1}{TWO}/my_file.txt"; $hash{2}{LOCATIONB} = "$hash{1}{TWO}/$hash{1}{ONE}/my_file.txt"; print "$hash{2}{LOCATIONA} = location a\n"; print "$hash{2}{LOCATIONB} = location b\n";
    as an example.
Re: Can a hash self reference?
by sapnac (Beadle) on Jul 01, 2005 at 15:49 UTC
    I think you are just trying to understand the concept. Take a look at this. It is tested

    Hope it helps...
    #!/usr/bin/perl -w use strict; use diagnostics; my %hash; $hash{1}{"ONE"}="testdir"; $hash{1}{"TWO"}="tmpdir"; $hash{2}{"LOCATIONA"} = $hash{1}{"ONE"}."/".$hash{1}{"TWO"}."/my_file. +txt"; $hash{2}{"LOCATIONB"} = $hash{1}{"TWO"}."/".$hash{1}{"ONE"}."/my_file. +txt"; print "$hash{2}{LOCATIONA} = location a\n"; print "$hash{2}{LOCATIONB} = location b\n";
      Thanks, I was trying to come up with some shortcuts and was failing miserably and the awnsers I got here reminded me I could do the following, this is the actual code.
      my %data = ( DATA => { DIR => "/prod" }, LOGS => { DIR => "/prod/logs" }, SITE1 => { DIR => "/prod/data1", FILE => "/prod/data1/LSTD.DAT" }, SITE2 => { DIR => "/prod/data2", FILE => "/prod/data2/LSTD.DAT" }, LOG1 => { FILE => "/prod/logs/stdaudit01_3 +289.log_1" }, LOG2 => { FILE => "/prod/logs/stdaudit02_8 +750.log_1" } ); # assign $data{$_}{'COPY_D'} and $data{$_}{'COPY_F'} Where needed for ( keys (%data) ) { if ( $data{$_}{'DIR'} ) { $data{$_}{'COPY_D'} = join '', $ARCHIVE +_DIR, $data{$_}{'DIR'} } if ( $data{$_}{'FILE'} ) { $data{$_}{'COPY_F'} = join '', $ARCHIVE +_DIR, $data{$_}{'FILE'} } }


      I just needed to provide an interface to do some copying once a flashcopy is made of a disk...

      Ted
      --
      "That which we persist in doing becomes easier, not that the task itself has become easier, but that our ability to perform it has improved."
        --Ralph Waldo Emerson
Re: Can a hash self reference?
by NetWallah (Abbot) on Jul 02, 2005 at 01:56 UTC
    You could get the results desired, if you delay their evaluation, and use slightly strange-looking syntax :
    my %h; %hash = ( 1 => { ONE => 'testdir', TWO => 'tmpdir' }, 2 => { LOCATIONA => sub{ qq($hash{1}{ONE}/$hash{1}{TWO}/my_f +ile.txt)}, # Note - wrapped in "sub" LOCATIONB => sub{qq($hash{1}{TWO}/$hash{1}{ONE}/my_fi +le.txt)} } ); print $hash{2}{LOCATIONA}(),qq( = location a\n); #When called like a sub call, produces: # testdir/tmpdir/my_file.txt = location a
    For complete consistency, you would probably wrap the values corresponding to ONE and TWO in sub's as well.

         "Income tax returns are the most imaginative fiction being written today." -- Herman Wouk

Re: Can a hash self reference?
by tphyahoo (Vicar) on Jul 02, 2005 at 08:48 UTC
    For what it's worth, self-reference is more commonly called circular reference. Objects with circular references need some guidance about how they should be garbage collected; it doesn't happen automatically. There is a very good discussion of this at Proxy Objects: Building Garbage Collected Circular References which also touches on what makes references circular in general, and how you can dissect them using devel::peek and other tools. Good luck!
      However, the OP here isn't actually talking about any kind of reference, much less a circular one. He just wants to use a value from one part of a data structure to create a value for another part.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2014-12-27 12:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls