Давайте изменим представление @new
, чтобы показать, что происходит:
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 уникальны, поэтому при присвоении @new
значению %hash
последнее значение для данной клавиши «выигрывает». Для простого примера
$ perl -le '%h = qw/1 a 1 b 1 c/; print $h{1}'
c
Учитывая, что у вас много значений для одного и того же ключа, используйте структуру данных, которая может его обработать:
my %hash;
for (my $i = 0; $i < @new; $i += 2) {
my($name,$val) = @new[$i,$i+1];
push @{ $hash{$name} } => $val;
}
Если вы не против уничтожить @new
, код может быть немного более идиоматическим:
while (@new) {
my($name,$val) = splice @new, 0, 2;
push @{ $hash{$name} } => $val;
}
Это означает, что каждое значение, связанное с данным ключом в %hash
, является ссылкой на массив значений. Оператор push
ожидает массив, а не ссылку, поэтому мы используем @{ ... }
для разыменования его.
Если вы не знакомы с ссылками на Perl, обязательно прочитайте документацию perlref и perllol .
Один из способов печати значений в %hash
- это
foreach my $name (sort keys %hash) {
print "$name = [@{ $hash{$name} }]\n";
}
Выход:
attribute = [Mandatory Mandatory]
max = [994048685 9940486857 F]
min = [0 0X00 0X00]
name = [Protocol_discriminator Security_header]
type = [nibble]
value = [7 778 778]
Еще одним удобным трюком для печати и отладки сложных структур данных является модуль Data::Dumper
:
use Data::Dumper;
print Dumper \%hash;
который печатает
$VAR1 = {
'attribute' => [
'Mandatory',
'Mandatory'
],
'value' => [
'7',
'778',
'778'
],
'min' => [
'0',
'0X00',
'0X00'
],
'name' => [
'Protocol_discriminator',
'Security_header'
],
'max' => [
'994048685',
'9940486857',
'F'
],
'type' => [
'nibble'
]
};