2012-05-24 2 views
1

Помогите мне исправить фрагмент кода.Perl hash negation

Я хочу указать сервер типа eq xyz, но не с namedservers.

our %SERVERS = (
    "rajesh1" => {type => 'xyz', sha => 'ram'}, 
    "rajesh2" => {type => 'xyz', sha => 'sita'}, 
    "rajesh3" => {type => 'xyz', named => ["raa"]}, 
    "rajesh4" => {type => 'xxx', named => ["rajjaj"]}, 
); 

while (my $mServer = each(%SERVERS)) 
{ 
    if ("$SERVERS{$mServer}{type}" eq "xyz" && !"$SERVERS{$mServer}{named}") 
    { 
    print "Name of the server is $mServer\n";   
    } 
} 

Ожидаемый результат:

rajesh1 
rajesh2

ответ

2
  1. Вам не хватает точки с запятой после определения %SERVERS.
  2. Вы начинаете называть его $mServer, а затем говорят $gServer. Выбери один!
  3. Избавьтесь от кавычек вокруг $SERVERS{$mServer}{type} и $SERVERS{$mServer}{named} (как только вы изменили gServer к mServer -вым их не нужны.
  4. Вы ожидаете увидеть «rajesh1 rajesh2», но ни один из них не имеет типа "prod". Как возможно ли это? Предположим, что вы изменить свой тип на "prod" ...
  5. вы ожидаете увидеть «rajesh1 rajesh2», но при печати "Name of the server is $mServer\n" (после изменения gServer к mServer). Изменение, что только "$mServer\n" и ...
  6. ... это должен работать.

Следовательно:

our %SERVERS = (
    "rajesh1" => {type => 'prod', sha => 'ram'}, 
    "rajesh2" => {type => 'prod', sha => 'sita'}, 
    "rajesh3" => {type => 'xyz', named => ["raa"]}, 
    "rajesh4" => {type => 'xxx', named => ["rajjaj"]}, 
); 

while (my $mServer = each %SERVERS) { 
    if ($SERVERS{$mServer}{type} eq "prod" && !$SERVERS{$mServer}{named}) { 
     print "$mServer\n"; 
    } 
} 

Тогда:

$ perl test.pl 
rajesh1 
rajesh2 
$ 
+0

Извините за опечатку. Я только что поправил. Позвольте мне пройти через ваши другие входы, а также –

+0

Спасибо. работает :) –

1

Вы ищете defined.

if ($SERVERS{$mServer}->{type} eq "xyz" && 
    ! defined $SERVERS{$mServer}->{named}) 
... 

Вы использовали неопределенную переменную $gServer, где, очевидно, вы имели в виду использовать переменную $mServer цикла. Вы должны use strict; use warnings; во всех своих сценариях; что позволяет легко поймать эту ошибку (и множество других).

Я использую оператор косвенности -> для доступа к содержимому хеш-ссылок в качестве предпочтительного. Я также удалил некоторые безвозмездные цитаты как стилистические изменения.

+3

Вы ** сделать не нужно использовать ** '->'; это подразумевается между скобками (см. [perlref's «Использование ссылок», пункт 3] (http://perldoc.perl.org/perlref.html#Using-References)), потому что вы не можете определить * не ссылки * хэш или массив как значение ключа. Это потребовалось бы только в том случае, если '$ SERVERS' был hashref, и мы имели в виду это, а не'% SERVERS'. Тем не менее, ваш код не сломается, так как я не сдуваю вас или что-то еще. – Ashe

+0

Len: Спасибо, обновил мой ответ. Некоторые из вещей, которые я испытывал, были исправлены изменениями к этому вопросу. – tripleee

+0

тоже! :) Я рад, что вы отметили '->' как вещь стиля (я не против этого сам по себе, просто не люблю видеть, что это называется обязательным, когда это не так). – Ashe

1

Полная выборка, ловя и возвращаемых значений each «s, что уменьшает визуальный беспорядок:

use strict; 
use warnings; 

our %SERVERS = (
    "rajesh1" => {type => 'xyz', sha => 'ram'}, 
    "rajesh2" => {type => 'xyz', sha => 'sita'}, 
    "rajesh3" => {type => 'xyz', named => ["raa"]}, 
    "rajesh4" => {type => 'xxx', named => ["rajjaj"]}, 
    "rajesh5" => {type => 'prod', sha => 'ram'}, 
    "rajesh6" => {type => 'prod', named => ["jajaja"]}, 
); 

while (my($mServer, $mData) = each %SERVERS) { 
    if ($mData->{type} eq "prod" && !$mData->{named}) { 
     print "Name of the server is $mServer\n"; 
    } 
}