Как я ссылаюсь на хеш внутри подпрограммы? - PullRequest
2 голосов
/ 20 декабря 2010

Я пытаюсь использовать функцию связи модуля Config :: IniFiles , но не могу понять, как ссылаться на хэш внутри подпрограммы.Если я удаляю функцию связывания и связанный код из подпрограммы, она прекрасно работает.

Я думаю, что эта строка будет работать, но говорит, что "$ cfg" не инициализирован.

use Config::IniFiles
sub config_file {
    my $cfg_file = 'settings.ini';
    my %cfg;
    tie %cfg, 'Config::IniFiles', ( -file => "$cfg_file" );

    #my $cfg = Config::IniFiles->new( -file => $cfg_file );

}

sub esx_host_check {
    my $esx_host = config_file()->$cfg{ESX}{host};
}

Я уверен, что это что-то простое, но я в тупике.

Ответы [ 3 ]

7 голосов
/ 20 декабря 2010

Во-первых, функция tie возвращает внутренний скрытый объект, который представляет связь, а не саму связанную переменную. Во-вторых, вы не можете вернуть множественное связанное значение (хеш или массив) из подпрограммы и заставить его работать так, как вы ожидаете. Вам нужно вернуть ссылку на множественное число, а затем разыменовать его, когда вам нужно его использовать.

use Config::IniFiles;

sub config_file {
    tie my %cfg, 'Config::IniFiles', -file => 'settings.ini';  # tie variable
    return \%cfg;  # return a reference to the tied variable
}

sub esx_host_check {
    my $esx_host = config_file()->{ESX}{host}; # call sub and dereference value
}

Если вы собираетесь использовать хеш-конфигурацию несколько раз, то, вероятно, лучше всего скомпилировать ее и затем кэшировать результат:

{my $cfg;
sub config_file {
    tie %$cfg, 'Config::IniFiles', -file => 'settings.ini' unless $cfg;
    return $cfg;
}}

Это немного отличается от описанного выше. Сначала мы устанавливаем config_file как замыкание вокруг закрытой переменной $cfg. Обратите внимание, что это скаляр, а не хеш. Затем в подпрограмме мы проверяем, была ли переменная инициализирована, а если нет, вызовем tie. tie передается первый аргумент %$cfg, который разыменовывает неопределенное значение как хеш, что приводит к сохранению ссылки на связанный хеш в $cfg.

Немного сложнее, но для этого метода потребуется только один раз создать конфигурационный хеш, что потенциально сэкономит много времени.

1 голос
/ 20 декабря 2010

(1) всегда начинайте свой код с use strict. Вы должны были получить предупреждение в esx_host_check() о неизвестном %cfg

(2) используйте use vars(...) для реализации "глобальных" идентификаторов:

use vars qw(%cfg);

sub one
    {
        tie %cfg, ....
    }

sub two
    {
        my $value = $cfg{foo}{bar};
    }
0 голосов
/ 20 декабря 2010

Вы объявляете% cfg с моим (хорошо!), Поэтому он виден только внутри подпрограммы config_file;Затем вы связываете его, который возвращает базовый объект Config :: IniFiles, и, поскольку это последняя запись функции, он возвращает этот объект ... Так что я не уверен, почему вы в первую очередь связываетевместо использования закомментированной строки.

В любом случае config_file () возвращает объект Config :: IniFiles.Затем вы пытаетесь вызвать метод с именем содержимого переменной $ cfg {ESX} {host} .. Переменной, которая не существует!

Если вы хотите использовать интерфейс связи, добавьтевозврат \% cfg;до конца config_file.Если вы хотите использовать интерфейс объекта ... Ну, я могу указать вам только документы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...