I have an array like so:
@switch_ports = ()
and then want to add 50 instances of this hash, to the switch_ports array.
%port = (data1 => 0, data2 => 0, changed => 0)
However, if I push my hash to the array:
push(@switch_ports, %port)
and I do print @switch_ports
, I just see:
data10data20changed0
so it just seems to be adding them to the array, (joining them) and if I try and loop the array and print the keys, it also fails.
Can you store a hash in an array?
Can you have an array of hashes?
I'm trying to get this:
switchports
0
data1
data2
changed
1
data1
....
thus:
foreach $port (@switchport) {
print $port['data1']
}
would return all of the data1 for all of the hashes in the array.
In Perl, array and hash members must be a single value. Before Perl 5.0, there was no (easy) way to do what you want.
However, in Perl 5 you can now use a reference to your hash. A reference is simply the memory location where the item is being stored. To get a reference, you put a backslash in front of the variable:
use feature qw(say);
my $foo = "bar";
say $foo; #prints "bar"
say \$foo; #prints SCALAR(0x7fad01029070) or something like that
Thus:
my @switch_ports = ();
my %port = ( data1 => 0, data2 => 0, changed => 0 );
my $port_ref = \%port;
push( @switch_ports, $port_ref );
And, you don't have to create $port_ref
:
my @switch_ports = ();
my %port = ( data1 => 0, data2 => 0, changed => 0 );
push( @switch_ports, \%port );
To get the actual value of the reference, simply put the symbol back on front:
#Remember: This is a REFERENCE to the hash and not the hash itself
$port_ref = $switch_ports[0];
%port = %{$port_ref}; #Dereferences the reference $port_ref;
print "$port{data1} $port{data2} $port{changed}\n";
Another shortcut:
%port = %{$port[0]}; #Dereference in a single step
print "$port{data1} $port{data2} $port{changed}\n";
Or, even shorter, dereferencing as you go along:
print ${$port[0]}{data1} . " " . ${$port[0]}{data2} . " " . ${$port[0]}{changed} . "\n";
And a little syntactic sweetener. It means the same, but is easier to read:
print $port[0]->{data1} . " " . $port[0]->{data2} . " " . $port[0]->{changed} . "\n";
Take a look at Perldoc's perlreftut and perlref. The first one is a tutorial.