我如何引用子程序中的哈希?

时间:2010-12-20 20:19:14

标签: perl

我正在尝试使用模块Config::IniFiles的tie函数,但我无法弄清楚如何在子例程中引用hash。如果我从子例程中删除tie函数和相关代码,它就能完美运行。

这是我认为可行的行,但告诉我“$ 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 个答案:

答案 0 :(得分:7)

首先,tie函数返回表示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的闭包。请注意,它是标量而不是散列。然后在sub中,我们检查变量是否已初始化,如果没有,则调用tietie传递%$cfg的第一个参数,它将未定义的值取消引用为散列,这样可以将绑定的散列引用存储到$cfg中。

虽然稍微复杂一点,但这种技术只需要构建一次配置哈希,这可能会节省大量时间。

答案 1 :(得分:1)

(1)始终使用use strict启动您的perl代码。您应该已在esx_host_check()中收到有关未知%cfg

的警告

(2)使用use vars(...)来实现“全局”标识符:

use vars qw(%cfg);

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

sub two
    {
        my $value = $cfg{foo}{bar};
    }

答案 2 :(得分:0)

你用我的(好!)声明%cfg,所以它只在config_file子中可见;然后绑定它,它返回底层的Config :: IniFiles对象,并且,因为它是函数的最后一个条目,它返回该对象...所以我不确定你为什么要在第一时间打领带,而不是仅仅使用注释行。

在任何情况下,config_file()都会返回一个Config :: IniFiles对象。然后尝试调用一个方法,该方法由变量$ cfg {ESX} {host}的内容命名。一个不存在的变量!

如果要使用tie界面,请添加return \%cfg;到config_file的末尾。如果你想使用对象界面..好吧,我只能指出你的文档。