Your code, but properly indented so it's readable.
$Interaction{$TrGene} = {
CisGene => $CisGene,
E => $e,
Q => $q,
};
push @{$Interaction{$TrGene}}, $CisGene;
Code explained:
You assign a list of key-value pairs to an anonymous hash, using curly brackets {}, and you assign that hash reference to the $TrGene key in the %Interaction hash. Then you try to use that value as an array reference by surrounding it with @{ ... }, which does not work.
If you enter a hash key with different values, you will overwrite them. Let's take some practical examples, it's really quite easy.
$Interaction{'foobar'} = {
CisGene => 'Secret code',
E => 'xxx',
Q => 'yyy',
};
Now you've stored a hash reference under the key 'foobar'. That hash is actually a free standing reference to a data structure. I think it's easier to keep track of structures if you think of them as scalars: A hash (or array) can only ever contain scalars.
The hash %Interaction may contain a number of keys, and if you have entered data like above, all the values will be hash references. E.g.:
$hash1 = { # note: curly brackets denote an anonymous hash
CisGene => 'Secret code',
E => 'xxx',
Q => 'yyy',
};
$hash2 = {
CisGene => 'some other value',
E => 'foo',
Q => 'bar',
};
%Interaction = ( # note: regular parenthesis denote a list
'foobar' => $hash1, # e.g. CisGene => 'Secret code', ... etc. from above
'barbar' => $hash2 # e.g. other key value pairs surrounded by {}
...
);
The type of value contained in $hash1 and $hash2 is now a reference, an address to data in memory. If you print it out print $hash1, you will see something like HASH(0x398a64).
Now, if you enter a new value into %Interaction, using an existing key, that key will be overwritten. Because a hash key can only ever contain one value: A scalar. In our case, a reference to a hash.
What you are trying to do in your example is using the value of the 'foobar' key as an array reference (which is silly, because as you now can see above, it's a hash reference):
push @{$Interaction{$TrGene}}, $CisGene;
Rewritten:
push @{ $hash1 }, 'Secret code'; # using the sample values from above
No... that doesn't work.
What you need is a new container. We'll make the value of the key 'foobar' an array reference instead:
%Interaction = (
'foobar' => $array1,
...
);
Where:
$array1 = [ $hash1, $hash2 ];
or
$array1 = [ # note the square brackets to create anonymous array
{ # curly brackets for anonymous hash
CisGene => 'Secret code',
E => 'xxx',
Q => 'yyy',
}, # comma sign to separate array elements
{ # start a new hash
CisGene => 'Some other value',
E => 'foo',
Q => 'bar',
} # end
]; # end of $array1
Now, this is all rather a cumbersome way to put things, so lets make it simpler:
$CisGene = 'foobar';
$e = 'xxx';
$q = 'yyy';
my $hash1 = {
CisGene => $CisGene,
E => $e,
Q => $q,
};
push @{$Interaction{$TrGene}}, $hash1;
Or you can do away with the temp variable $hash1 and assign it directly:
push @{$Interaction{$TrGene}}, {
CisGene => $CisGene,
E => $e,
Q => $q,
};
And when accessing the elements:
for my $key (keys %Interaction) { # lists the $TrGene keys
my $aref = $Interaction{$key}; # the array reference
for my $hashref (@$aref) { # extract hash references, e.g. $hash1
my $CisGene = $hashref->{'CisGene'};
my $e = $hashref->{'E'};
my $q = $hashref->{'Q'};
}
}
Note the use of the arrow operator when dealing directly with references. You can also say $$hashref{'CisGene'}.
Or directly:
my $CisGene = $Interaction{'foobar'}[0]{'CisGene'};
I recommend reading perldata. A very handy module is Data::Dumper. If you do:
use Data::Dumper;
print Dumper \%Interaction; # note the backslash, Dumper wants references
It will print out your data structure for you, which makes it very easy to see what you are doing. Make note of it's use of brackets and curly brackets to denote arrays and hashes.