Упорядоченный по Perl многомерный хэш (используйте Хэш::Упорядоченный)

#perl #hash

Вопрос:

Я пытаюсь просмотреть многомерный хэш в Perl в точном порядке, в котором я его создал. Я использую Hash::Заказал, но не могу заставить его работать.

Если я использую Data::Dumper для печати $MENU_ITEMS, я вижу хэш-элементы, которые я ожидаю (см. Ниже), однако, когда я пытаюсь ввести их в $ITEM, он пуст.

Я уверен, что делаю что-то глупое, пожалуйста, помогите 🙂

 use Hash::Ordered;
$MENU_SECTIONS = Hash::Ordered->new
    (
    'MENU_manage_properties' => 
        {
        'show_current_properties'  => 'Current Properties',
        'show_prospect_properties' => 'Prospect Properties'
        },
    'MENU_reports' => 
        {
        'some_report'             => 'Some report',
        'another_report'          => 'Another report'
        },
    'MENU_settings' => 
        {
        'settings_here'           => 'Settings',
        'more_settings'           => 'More Settings'
        }
    );

%MENU_SECTIONS_HTML = ();

use Data::Dumper;
print header();

$menu_iterator = $MENU_SECTIONS->iterator;
while( (my $MENU_SECTION, my $MENU_ITEMS) = $menu_iterator->() ) 5
    {
    print "<hr>my $MENU_SECTION, my $MENU_ITEMS<br>";
    print "Dumper print of MENU_ITEMS:<br>";
    print Dumper $MENU_ITEMS;
    print "<br><br>";

    my $ITEM = Hash::Ordered->new(@MENU_ITEMS);
    $item_iterator = $ITEM->iterator;
    print "Dumper print of ITEM:<br>";
    print Dumper $ITEM;
    print "<br><br>";

    print "Dumper print of item_iterator:<br>";
    print Dumper $item_iterator;
    print "<br><br>";

    while( (my $OPERATION, my $TITLE) = $item_iterator->() ) 
        {
        print "my $OPERATION, my $TITLE<be>";
        }
    }
 

Вывод, который я получаю:

 my MENU_manage_properties, my HASH(0x43a21f0)
Dumper print of MENU_ITEMS:
$VAR1 = { 'show_current_properties' => 'Current Properties', 'show_prospect_properties' => 'Prospect Properties' };

Dumper print of ITEM:
$VAR1 = bless( [ {}, [], undef, 0, 0 ], 'Hash::Ordered' );

Dumper print of item_iterator:
$VAR1 = sub { "DUMMY" };

my MENU_tenants, my HASH(0x4397b80)
Dumper print of MENU_ITEMS:
$VAR1 = { 'show_current_tenants' => 'Current Tenants', 'show_prospect_tenants' => 'Prospect Tenants' };

Dumper print of ITEM:
$VAR1 = bless( [ {}, [], undef, 0, 0 ], 'Hash::Ordered' );

Dumper print of item_iterator:
$VAR1 = sub { "DUMMY" };

my MENU_buyers, my HASH(0x4317590)
Dumper print of MENU_ITEMS:
$VAR1 = { 'show_prospect_buyers' => 'Prospect Buyers', 'show_current_buyers' => 'Current Buyers' };

Dumper print of ITEM:
$VAR1 = bless( [ {}, [], undef, 0, 0 ], 'Hash::Ordered' );

Dumper print of item_iterator:
$VAR1 = sub { "DUMMY" };

my MENU_reports, my HASH(0x43175f0)
Dumper print of MENU_ITEMS:
$VAR1 = { 'some_report' => 'Some report', 'another_report' => 'Another report' };

Dumper print of ITEM:
$VAR1 = bless( [ {}, [], undef, 0, 0 ], 'Hash::Ordered' );

Dumper print of item_iterator:
$VAR1 = sub { "DUMMY" };

my MENU_settings, my HASH(0x4317650)
Dumper print of MENU_ITEMS:
$VAR1 = { 'more_settings' => 'More Settings', 'settings_here' => 'Settings' };

Dumper print of ITEM:
$VAR1 = bless( [ {}, [], undef, 0, 0 ], 'Hash::Ordered' );

Dumper print of item_iterator:
$VAR1 = sub { "DUMMY" }; 
 

Комментарии:

1. Всегда use strict; use warnings . Всегда. Вы написали @MENU_ITEMS вместо @$MENU_ITEMS ; strict предупредили бы вас.

2. Правильно, $MENU_ITEMS это не ссылка на массив, это хэш-ссылка. Я не знаю, что ты хотел с этим сделать, но ты должен знать. В любом случае, @MENU_ITEMS это не существующая переменная, поэтому вы должны видеть, что с вашим кодом что-то не так. Возможно %$MENU_ITEMS .

3. (хотя, вероятно, не имеет особого смысла преобразовывать неупорядоченный хэш в упорядоченный хэш)

4. Это потому, что вы создали хэш, используя { ... } , в то время как вы должны были использовать Hash::Ordered->new внутри первого Hash::Ordered->new .

5. Мне интересно, не следует ли вам использовать массивы, а не хэши, хотя.

Ответ №1:

Спасибо @Dada за помощь, вот рабочий код:

 use Hash::Ordered;
$MENU_SECTIONS = Hash::Ordered->new
    (
    'MENU_manage_properties' => 
        Hash::Ordered->new(
        'show_current_properties'  => 'Current Properties',
        'show_prospect_properties' => 'Prospect Properties'
        ),
    'MENU_reports' =>
        Hash::Ordered->new(
        'some_report'             => 'Some report',
        'another_report'          => 'Another report'
        ),
    'MENU_settings' =>
        Hash::Ordered->new(
        'settings_here'           => 'Settings',
        'more_settings'           => 'More Settings'
        )
    );


$menu_iterator = $MENU_SECTIONS->iterator;
while( (my $MENU_SECTION, my $MENU_ITEMS) = $menu_iterator->() )
    {
    my $ITEM = Hash::Ordered->new($MENU_ITEMS->as_list);
    $item_iterator = $ITEM->iterator;

    while( (my $OPERATION, my $TITLE) = $item_iterator->() )
        {
        ## DO something with $OPERATION and $TITLE
        }

    }