2015-06-02 4 views
2

я в настоящее время имеют следующиеНе удается правильно объединить хэши

# $dog, $cat, $rat are all hash refs 

       my %rethash = ('success' => 'Your Cool'); 

       my %ref ={ 'dog' => $dog, 'cat' => $cat, 'mouse' => $rat, 
           'chicken' => '' }; 

       my $perlobj = (\%ref,\%rethash);  

Когда $ perlobj сваливается это результат

$VAR1 = { 
     'success' => 'Your Cool' 
    }; 

Однако, когда предупреждения включены, я получаю следующее сообщение

Useless use of reference constructor in void context at .. 

Я понимаю, что есть что-то ужасно неправильно с тем, как% ref назначается с помощью {}, что не так с этим кодом? Я не могу избавиться от этого предупреждения ....

EDIT: Хорошо, я думаю, что я понял, что происходит,

my $perlobj = (\%ref,\%rethash); 

Это не слияние, но результаты в $ perlobj становится ссылка на% rethash, это очевидно после прочтения ваших ответов.

+4

вы используете '{}' при создании '% ref', когда вы должны использовать'() ' – RobEarl

+1

Вы также хотите: 'my% perlobj = (% ref,% rethash);' – RobEarl

+1

Возможный дубликат [Как объединить хэши в Perl?] (Http://stackoverflow.com/questions/350018/how-can-i -combine-hashes-in-perl) – RobEarl

ответ

5

Что говорит RobEarl правильно. Я объясню это и добавлю еще кое-что.

Ваше имя переменной %ref и тот факт, что вы используете {}, означает, что вы хотите получить ссылку здесь.

Давайте посмотрим, какое значение у нас будет в %ref. Рассмотрим этот пример.

use strict; use warnings; 
use Data::Printer; 
my %foo = { key => 'value' }; 
p %foo; 

Это выбросит предупреждение Reference найденного где даже размер список ожидаемого на моем Perl 5.20.2. Вывод будет:

{ 
    HASH(0x7e33c0) undef 
} 

Это хэш с hashref в качестве ключа и undef в качестве значения. HASH(0x07e33c0) - это то, что вы получаете, когда смотрите на хеш-ссылку, не разыгрывая ее. ({} есть, потому что Data :: Printer преобразует хэш в hashref).

Назад к вашему коду, правильная сигила для справки $. Неважно, что это за ссылка. Ссылка всегда является скаляром (указатель на место в памяти, где хранится хэш/массив/что-то).

my $ref = { 
    dog  => $dog, 
    cat  => $cat, 
    mouse => $rat, 
    chicken => '', # maybe this should be undef? 
}; 

Теперь у вас есть hashref со значениями $dog, $cat, $rat и пустая строка.

Теперь вы назначаете переменную с именем $perlobj, что означает, что это объект. Вместо этого вы назначаете скалярную переменную ($ делает ее скаляром) со списком. Если вы это сделаете, Perl присвойт только самое правое значение переменной.

my $foo = (1, 2, 3); # $foo will be 3 and there's a warning 

Вы назначаете список из двух ссылок. Первый из них не учитывается и назначается только \$rethash. Это работает, потому что удобно, $perlobj является скаляром, а ссылки также являются скалярами. Итак, теперь $perlobj является ссылкой %rethash. Вот почему ваш вывод Data :: Dumper выглядит как %rethash.

Я не уверен, что вы хотите сделать, поэтому я не могу вам помочь. Я предлагаю вам кое-что прочитать.

  • perlreftut полезно узнать, как ссылки работают
  • Если вы хотите сделать объектно-ориентированное программирование, проверить Moose
  • Это может быть полезно, чтобы просто пойти получить книгу, чтобы узнать немного больше об основных Perl. Learning Perl по Рэндал Л. Шварц и Начиная с Perl Кертис Poe оба очень хороши для этого
+0

Спасибо, что сломал его. Я очень ценю это, я проходил какой-то старый код и добавил предупреждения к модулю и нашел эту ошибку. – ingueni

2

Вы принимаете список ссылок на хэши и назначая их на скаляр

my $perlobj = (\%ref, \%rethash); # same as $perlobj = \%rethash 

Вместо этого вы хотите, чтобы получить ссылку на слияние хэшей

my $perlobj = { %ref, %rethash }; 
Смежные вопросы