我正在尝试使用模块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};
}
我确信这很简单,但我很难过。
答案 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中,我们检查变量是否已初始化,如果没有,则调用tie
。 tie
传递%$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的末尾。如果你想使用对象界面..好吧,我只能指出你的文档。