hash reference as a hash key

S

Steve

Dear folks

I have a data structure which is an array of hashes of hash
references.
I need to consider each element in turn and retrieve a related set of
values
from a hash of hashes of hashes.

The choppped-down code fragment below should give you the idea.

It seems to work as (I) expected, but what worries is me is that I
realise that I don't actually
understand what I am doing here. When I loop with $each_marker and
$eachDNA the variable I
pull out is a hash ref. I am then using that to provide the key to the
hashes. I could
use some unique component within each pointed-to hash; eg I could
refer
to $pcr_well{$each_marker->{'locus_id'}}{$eachDNA->{'sample_id'}}{plate}
rather than
$pcr_well{$each_marker}{$eachDNA}{plate}. However I would need to be
sure that each will always
point to a unique value and while that is true now, who knows how the
underlying db may change.

Is it safe/sensible to continue to do it like this, I suppose my real
concern is that I don't
have a mental image of what $each_marker and $eachDNA actually *are*
during these loops, will
they suddenly mutate on me ?!

Thanks for any thoughts and advice


foreach my $each_marker (@{$search_result{'markers'}}){

foreach my $eachDNA (@{$search_result{DNA}}){

$pcr_plate_position=$pcr_well{$each_marker}{$eachDNA}{plate};
$pcr_row= $pcr_well{$each_marker}{$eachDNA}{row};
$pcr_col= $pcr_well{$each_marker}{$eachDNA}{col};

print ROBOT qq!$myparams{'pcr_plate_type'}[0]\t
$pcr_plate_position\t$pcr_plate_barcode\t$row_sequence{$pcr_pl_type}[$pcr_row]$pcr_col\t$wash_or_not!;
print ROBOT qq!\t$step: $MM_vol ul $each_marker->{'locus_id'}
master mix into well for DNA $eachDNA->{'DNA'}
$eachDNA->{'Sample_id'}\n!;

}
}
 
J

Jay Tilton

(e-mail address removed) (Steve) wrote:

: Subject: hash reference as a hash key

See perlfaq4, "How can I use a reference as a hash key?"

[snip]

: Is it safe/sensible to continue to do it like this, I suppose my real
: concern is that I don't have a mental image of what $each_marker and
: $eachDNA actually *are* during these loops,

They are hash references that have been stringified, e.g.
"HASH(0x155ac58)" . After stringification, they are no longer real
references; they are more akin to symbolic references.

: will they suddenly mutate on me ?!

There is no guarantee that the hash in the original location will be the
same, or that it will exist at all.

my %foo = (
{ 'key' => 'something very important' } => 'something else'
);

for( keys %foo ) {
# $_ is a symbolic reference to the anonymous hash,
# which has been already been garbage-collected.
print $_->{'key'}; # oops
}
 
U

Uri Guttman

JT> : Is it safe/sensible to continue to do it like this, I suppose my real
JT> : concern is that I don't have a mental image of what $each_marker and
JT> : $eachDNA actually *are* during these loops,

JT> They are hash references that have been stringified, e.g.
JT> "HASH(0x155ac58)" . After stringification, they are no longer real
JT> references; they are more akin to symbolic references.

not exactly as you can't ever dereference a stringified ref. you can do
that with symrefs (even though it is evil).

refs as keys are a fine thing as long as the ref itself is also in the
value part (either the value itself or inside someother structure which
is the value). one simple use for this is to track a set of objects by
their references. you can search/add/delete from a hash which has the
object as both the key and the value.

uri
 
J

Jay Tilton

:
: JT> They are hash references that have been stringified, e.g.
: JT> "HASH(0x155ac58)" . After stringification, they are no longer real
: JT> references; they are more akin to symbolic references.
:
: not exactly as you can't ever dereference a stringified ref.

Damn. I would have sworn I had done it before, but I can't make it
happen again.
 
S

Steve

refs as keys are a fine thing as long as the ref itself is also in the
value part (either the value itself or inside someother structure which
is the value). one simple use for this is to track a set of objects by
their references. you can search/add/delete from a hash which has the
object as both the key and the value.

uri

Do you mean I could add a value such as
$eachDNA->{uniqueaddress} = $eachDNA;
and then use that as a hash key ?

I can see how that is better than what I am presently doing, but not
fundamentally different. I can of course ensure that the hashref will
remain in existence, but does that mean that it won't change its value
when stringified ? If not I still risk that happening before I capture
a unique value within the data structure.

Steve
 
S

Steve Grazzini

Steve said:
Do you mean I could add a value such as
$eachDNA->{uniqueaddress} = $eachDNA;
and then use that as a hash key ?

That's a circular reference, so it's not the ideal solution.
I can see how that is better than what I am presently doing, but not
fundamentally different. I can of course ensure that the hashref will
remain in existence, but does that mean that it won't change its value
when stringified ?

Yes. Unless you bless() the reference, the stringified form will
stay the same until the object is destroyed.
 
S

Steve

Steve Grazzini said:
That's a circular reference, so it's not the ideal solution.

oops I meant to say $eachDNA->{uniqueaddress} = "$eachDNA";
Yes. Unless you bless() the reference, the stringified form will
stay the same until the object is destroyed.

OK, I will relax,

Thanks

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top