CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
creating reference from within hash?

 



zohman
Novice

May 24, 2017, 11:09 PM

Post #1 of 6 (2241 views)
creating reference from within hash? Can't Post

Hi,

Iv'e some hard-coded hash, where some nested values may repeat them-self and i don't want to write them in every value in the hash..

for example:

Code
my %Hash = ( 'TestApp' => { id => 'APP10', host => 'host1' }, 
'TestAppV2' => { id => 'APP10', host => 'host2' },
'TestApp2' => { id => 'APP11', host => 'host43' },
'TestApp2V2' => { id => 'APP11', host => 'host49' }
);


as you can see above:
$hash{'TestApp'}{'id'} = APP10;
and also
$hash{'TestAppV2'}{'id'} = APP10;

it is possible to make a reference inside the hash to point to the first value?
so for the TestApp scenario it will be something like this:


Code
my %Hash = ( 'TestApp' => { id => 'APP10', host => 'host1' }, 
'TestAppV2' => { id => $hash{'TestApp'}{id}, host => 'host2' }
);


Thanks.


Laurent_R
Veteran / Moderator

May 25, 2017, 1:35 AM

Post #2 of 6 (2236 views)
Re: [zohman] creating reference from within hash? [In reply to] Can't Post

Maybe I misunderstand what you're trying to do or I am otherwise confused, but I have the feeling you can't really do what you want, because in:


Code
'TestAppV2' => { id => $hash{'TestApp'}{id}, host => 'host2' }

the "$hash{'TestApp'}{id}" will be evaluated to its content, so that you will effectively end up with the same hash as your original one. I am afraid that this will happen even if you use a reference to "$hash{'TestApp'}{id}".

The closest to what you're trying to do that I could come up with is to store the reference as a sting within single quotes to prevent interpolation:


Code
use strict; 
use warnings;
use Data::Dumper;

my %Hash = ( 'TestApp' => { id => 'APP10', host => 'host1' },
'TestAppV2' => { id => 'APP10', host => 'host2' },
'TestApp2' => { id => 'APP11', host => 'host43' },
'TestApp2V2' => { id => 'APP11', host => 'host49' }
);

print "Before: ", Dumper \%Hash;

my %temp_hash;
for my $key (keys %Hash) {
my $id = $Hash{$key}{id};
if (exists $temp_hash{$id}) {
$Hash{$key}{id} = $temp_hash{$id};
} else {
$temp_hash{$id} = '$Hash{$key}{id}';
}
}

# print Dumper \%temp_hash;
print "\nAfter: ", Dumper \%Hash;


This would display the following:


Code
$ perl nested_hash.pl 
Before: $VAR1 = {
'TestApp2' => {
'id' => 'APP11',
'host' => 'host43'
},
'TestApp2V2' => {
'id' => 'APP11',
'host' => 'host49'
},
'TestAppV2' => {
'id' => 'APP10',
'host' => 'host2'
},
'TestApp' => {
'id' => 'APP10',
'host' => 'host1'
}
};

After: $VAR1 = {
'TestApp2' => {
'id' => 'APP11',
'host' => 'host43'
},
'TestApp2V2' => {
'id' => '$Hash{$key}{id}',
'host' => 'host49'
},
'TestAppV2' => {
'id' => 'APP10',
'host' => 'host2'
},
'TestApp' => {
'id' => '$Hash{$key}{id}',
'host' => 'host1'
}
};



But I doubt that's really what you need, because you won't be able to do much with these strings (well, you can eval them if $key is properly defined at the point where you need it, but that does not seem to buy you very much).

This seems to be a XY problem, i.e. a case where you think you can solve the X problem by using Y, and ask about Y. May be should should tell us about X, that is about the real underlying thing that you want to achieve.

Or, again, perhaps I am confused about your question.


(This post was edited by Laurent_R on May 25, 2017, 1:51 AM)


zohman
Novice

May 25, 2017, 5:37 AM

Post #3 of 6 (2228 views)
Re: [Laurent_R] creating reference from within hash? [In reply to] Can't Post

i probably didn't clarify so well,
as i said, inside the script the %hash is hard-coded,
i don't need $Hash{$key}{id} as a string, i want it's value to be there.
so if we using DUMPER output, the before and after will be the same like this:


Code
 $VAR1 = {  
'TestApp' => {
'id' => 'APP10',
'host' => 'host1'
},
'TestAppV2' => {
'id' => 'APP10',
'host' => 'host2'
}
};


but IN the code i want to put:


Code
my %Hash = {  
'TestApp' => {
'id' => 'APP10',
'host' => 'host1'
},
'TestAppV2' => {
'id' => $Hash{'TestApp'}{id},
'host' => 'host2'
}
};



here is another example,
IN the script code:


Code
my %Hash = {  
'TestApp' => {
'id' => 'APP10',
'host' => 'host1'
},
'TestAppV2' => {
'id' => $Hash{'TestApp'}{id},
'host' => 'host339'
},
'TestAppV3' => {
'id' => $Hash{'TestApp'}{id},
'host' => 'host222'
},
'TestAppV4' => {
'id' => $Hash{'TestApp'}{id},
'host' => 'host21'
}
};


Dumper:



Code
my %Hash = {  
'TestApp' => {
'id' => 'APP10',
'host' => 'host1'
},
'TestAppV2' => {
'id' => 'APP10',
'host' => 'host339'
},
'TestAppV3' => {
'id' => 'APP10',
'host' => 'host222'
},
'TestAppV4' => {
'id' => 'APP10',
'host' => 'host21'
}
};



if i call $hash{'TestAppV4'}{id} within the code i want to get the hash{'TestApp'}{id} value which is 'APP10'.

make sense?


FishMonger
Veteran / Moderator

May 25, 2017, 8:24 AM

Post #4 of 6 (2222 views)
Re: [zohman] creating reference from within hash? [In reply to] Can't Post

It appears to me that you have an XY problem. Which is to say that you've decided on an incorrect solution X and are asking to solve that without explaining problem Y.

I suspect that the better/proper solution would be to use a different data structure; possibly a HoA or AoH. For now I'll address your current hash question.

Your hash definition is close. To accomplish your goal you can't declare and define the hash in 1 statement. You'll need to break it up to individual assignments.

Your current assignments of the id are making a copy of the first one, not a reference to it which means they won't change if/when the first one changes.

You also need to make sure you de-reference those "copies" when used.


Code
#!/usr/bin/perl 

use 5.010;
use warnings;
use strict;
use Data::Dumper;

my %Hash;

$Hash{'TestApp'} = {
'id' => 'APP10',
'host' => 'host1'
};

$Hash{'TestAppV2'} = {
'id' => \$Hash{'TestApp'}{id},
'host' => 'host339'
};

$Hash{'TestAppV3'} = {
'id' => \$Hash{'TestApp'}{id},
'host' => 'host222'
};

$Hash{'TestAppV4'} = {
'id' => \$Hash{'TestApp'}{id},
'host' => 'host21'
};

say Dumper \%Hash;

$Hash{'TestApp'}{id} = 'id altered';
say ${$Hash{'TestAppV4'}{id}};

$Hash{'TestApp'}{id} = 'id altered again';
say ${$Hash{'TestAppV3'}{id}};


c:\test>Perl-1.pl

Code
$VAR1 = { 
'TestApp' => {
'host' => 'host1',
'id' => 'APP10'
},
'TestAppV2' => {
'id' => \$VAR1->{'TestApp'}{'id'},
'host' => 'host339'
},
'TestAppV3' => {
'id' => \$VAR1->{'TestApp'}{'id'},
'host' => 'host222'
},
'TestAppV4' => {
'host' => 'host21',
'id' => \$VAR1->{'TestApp'}{'id'}
}
};

id altered
id altered again



(This post was edited by FishMonger on May 25, 2017, 8:29 AM)


zohman
Novice

May 27, 2017, 10:31 PM

Post #5 of 6 (2196 views)
Re: [FishMonger] creating reference from within hash? [In reply to] Can't Post

yes, i understand you,
I thought there is something shorter.

Thanks!


Laurent_R
Veteran / Moderator

May 28, 2017, 10:19 PM

Post #6 of 6 (2174 views)
Re: [zohman] creating reference from within hash? [In reply to] Can't Post

There might be something shorter, but not within the constraints of what you're asking. If you explained the underlying problem you're trying to solve, rather than asking for a specific implementation that you believe to be the best (and if quite unlikely to be), we may be able to provide a better (and more meaningful) solution.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives