2009-07-21 2 views
22

Мне было предложено изменить какой-либо существующий код, чтобы добавить некоторые дополнительные функции. Я искал в Google и не могу найти ответ. У меня есть кое-что для этого эффекта ...Как использовать хэши в качестве аргументов для подпрограмм в Perl?

%first_hash = gen_first_hash(); 
%second_hash = gen_second_hash(); 
do_stuff_with_hashes(%first_hash, %second_hash); 

sub do_stuff_with_hashes 
{ 
    my %first_hash = shift; 
    my %second_hash = shift; 

    # do stuff with the hashes 
} 

Я получаю следующие ошибки:

Odd number of elements in hash assignment at ./gen.pl line 85. 
Odd number of elements in hash assignment at ./gen.pl line 86. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143. 

Line 85 и 86 представляют собой первые две строки в подпрограмму и 124 и 143, где я я получаю доступ к хэшам. Когда я просматриваю эти ошибки, кажется, что мои хеши неинициализированы. Тем не менее, я могу проверить, что хеши имеют значения. Почему я получаю эти ошибки?

+1

Это дубликат. Пожалуйста, взгляните на http://stackoverflow.com/questions/944784/ – innaM

ответ

24

Хэши сворачиваются в плоские списки, когда вы передаете их в функцию. Итак, когда вы смещаете значение из аргументов функции, вы получаете только одно значение. То, что вы хотите сделать, это передать хеши по ссылке.

do_stuff_with_hashes(\%first_hash, \%second_hash); 

Но тогда вы должны работать с хешами как ссылки.

my $first_hash = shift; 
my $second_hash = shift; 
+0

Я вижу ... Это трюк ... Спасибо большое! – predhme

5

Во-первых,

do_stuff_with_hashes(%first_hash, %second_hash); 

"потоки" хэши в список, что эквивалентно:

('key1_1', 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

, а затем выбрать один и только один из этих пунктов. Так,

my %first_hash = shift; 

, как говорят:

my %first_hash = 'key1_1'; 
# leaving ('value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

Вы не можете иметь хэш как { 'key1' }, так как 'key1' это отображение ничего.

+1

Спасибо за объяснение того, что происходило за кулисами. – predhme

9

Хеш-ссылки - это путь, как указывали другие.

Предоставление другого способа сделать это только для пинков ... потому что кому нужны переменные темпа?

do_stuff_with_hashes({ gen_first_hash() }, { gen_second_hash() }); 

Здесь вы просто создать хэш ссылок на лету (через фигурные скобки вокруг вызовов функций) для использования в функции do_stuff_with_hashes. Это ничего особенного, другие методы столь же действительны и, вероятно, более ясны. Это может помочь в будущем, если вы видите эту активность в своих путешествиях как кто-то, кто не знаком с Perl.

+0

Отличный трюк! Я держу это вокруг. – predhme

+0

Счастливый обязать. Одно дело иметь в виду, если вы будете придерживаться в Perl, так это то, что все укажут, как «Существует несколько способов сделать это». Это своего рода благословение и проклятие) в зависимости от вашего мнения о таких вещах) в программировании на Perl. Повеселись! –

14

Немного поздно, но,

Как было сказано, вы должны передавать ссылки, а не хэши.

do_stuff_with_hashes(\%first_hash, \%second_hash); 

Но если вам нужно/хотите использовать ваши хеши как таковые, вы можете разыменовать их imediatly.

sub do_stuff_with_hashes { 
    my %first_hash = %{shift()}; 
    my %second_hash = %{shift()}; 
}; 
+0

, чтобы быть ясным, я не разыгрываю хэши, я их копирую. – larelogio

Смежные вопросы