Let's change the presentation of @new to show what's going on:
my @new = qw/
attribute Mandatory
attribute Mandatory
max 994048685
max 9940486857
max F
min 0
min 0X00
min 0X00
name Protocol_discriminator
name Security_header
type nibble
value 7
value 778
value 778
/;
Perl hash keys are unique, so when assigning @new to %hash, the last value for a given key “wins.” For a simple example
$ perl -le '%h = qw/1 a 1 b 1 c/; print $h{1}'
c
Given that you have many values for the same key, use a data structure that can handle it:
my %hash;
for (my $i = 0; $i < @new; $i += 2) {
my($name,$val) = @new[$i,$i+1];
push @{ $hash{$name} } => $val;
}
If you don't mind destroying @new, the code can be a little more idiomatic:
while (@new) {
my($name,$val) = splice @new, 0, 2;
push @{ $hash{$name} } => $val;
}
This means every value associated with a given key in %hash is a reference to an array of values. The push operator expects an array and not a reference, so we use @{ ... } to dereference it.
If you aren't familiar with Perl references, be sure to read the perlref and perllol documentation.
One way to print the values in %hash is
foreach my $name (sort keys %hash) {
print "$name = [@{ $hash{$name} }]\n";
}
Output:
attribute = [Mandatory Mandatory]
max = [994048685 9940486857 F]
min = [0 0X00 0X00]
name = [Protocol_discriminator Security_header]
type = [nibble]
value = [7 778 778]
Another handy trick for printing and debugging complex data structures is the Data::Dumper module:
use Data::Dumper;
print Dumper \%hash;
which prints
$VAR1 = {
'attribute' => [
'Mandatory',
'Mandatory'
],
'value' => [
'7',
'778',
'778'
],
'min' => [
'0',
'0X00',
'0X00'
],
'name' => [
'Protocol_discriminator',
'Security_header'
],
'max' => [
'994048685',
'9940486857',
'F'
],
'type' => [
'nibble'
]
};
name, and the latter overwrites the former. What would you like your hash to do with them? Should they become two subhashes?