Как проверить, определен ли хеш Perl, если у него нет пар ключ / значение - PullRequest
1 голос
/ 27 июля 2011

Примечание об обновлении: я изменил этот вопрос, чтобы, надеюсь, задать его лучше.Первоначально у меня было больше кода, который пытался продемонстрировать то, что я хотел, но это только мешало.Также я делал ссылки на «определенные».Оказывается, это было не то, что я хотел.Обновленный вопрос должен прояснить, что я пытаюсь сделать.


Я пытаюсь найти способ проверить, был ли объявлен хеш в скрипте perl внутри модуляfunction.

Имеется следующий скрипт (script.pl):

#!/usr/bin/perl -w

use strict; 
use checkHash;

our %testHash = ("key"=>"value");

print &checkHash() ? 1 : 0;

Вместе с этим модулем (checkHash.pm);

sub checkHash { 
    if(%main::testHash) { 
        return 1; 
    }
    else { 
        return 0; 
    }
}

1;

Работает на Macс OS X 10.6.7 и perl v5.10.0 возвращаемое значение checkHash равно «1», что я и ожидал.Однако, если я удаляю пару ключ-значение из скрипта, изменив строку:

our %testHash = ("key"=>"value");

на:

our %testHash = ();

Возвращаемое значение равно «0».Мое первоначальное предположение было, что это будет «1», но после прочтения о том, как тест, который я использую, проверяет размер в хэше, я понимаю, почему это неправильное мышление.

Мои вопросы:

Есть ли тест, который можно использовать в модуле checkHash, который вернет true, если хэш, который он тестирует, существует, но ему не назначены какие-либо ключик этому?

Ответы [ 4 ]

4 голосов
/ 27 июля 2011

Проверка того, был ли данный символ объявлен, почти наверняка бесполезна, и желание выполнить его указывает на проблему проектирования.Однако, для полноты, вот тесты для лексических и динамических символов:

Узнайте, был ли объявлен лексический символ $whoopee:

use Try::Tiny;
my $declared = try { use strict; $whoopee; 1 };

Узнайте, есть ли какие-либо динамическиеобъявлен символ с именем FooPackage::whoopee (включая хэши, которые пишут их имена %FooPackage::whoopee):

my $declared = exists $FooPackage::{whoopee};
4 голосов
/ 27 июля 2011

define () не является значимым тестом для агрегатов (массивов и хэшей). perldoc -f определен имеет это, чтобы сказать:

Использование «определено» для агрегатов (хэшей и массивов) не рекомендуется.Раньше сообщалось, была ли выделена память для этого агрегата.Такое поведение может исчезнуть в будущих версиях Perl.Вместо этого вы должны использовать простой тест для размера:

               if (@an_array) { print "has array elements\n" }
               if (%a_hash)   { print "has hash members\n"   }
1 голос
/ 27 июля 2011

См. perldoc perldata

Если вы оцениваете хеш в скалярном контексте, он возвращает false, если хеш пуст. Если есть какие-либо пары ключ / значение, возвращается true; точнее, возвращаемое значение представляет собой строку, состоящую из числа используемых сегментов и количества выделенных сегментов, разделенных косой чертой.

Это объясняет, почему ваш defined тест, похоже, сработал.

1 голос
/ 27 июля 2011

Вы можете просто посчитать ключи:

sub checkHash {
    return ( scalar keys %main::testHash ) ? 1 : 0;
}

perl -le 'my %h; print ( scalar keys %h ) ? 1 : 0;'
0
perl -le 'my %h = (foo=>1); print ( scalar keys %h ) ? 1 : 0;'
1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...