如何在Perl中创建一个嵌套哈希常量?

6

我想在Perl中实现与以下Ruby代码等效的功能:

class Foo
  MY_CONST = {
    'foo' => 'bar',
    'baz' => {
      'innerbar' => 'bleh'
    },
  }

  def some_method
    a = MY_CONST[ 'foo' ]
  end

end

# In some other file which uses Foo...

b = Foo::MY_CONST[ 'baz' ][ 'innerbar' ]

也就是说,我想声明一个常量的嵌套哈希结构,既可以在类内部使用,也可以在外部使用。怎么做?


我已经设置好了我的Perl类(使用bless等),所以不需要被展示如何做。 - Pistos
4个回答

11

您也可以完全使用内置函数实现此操作:

package Foo;
use constant MY_CONST =>
{
    'foo' => 'bar',
    'baz' => {
        'innerbar' => 'bleh',
    },
};

sub some_method
{
    # presumably $a is defined somewhere else...
    # or perhaps you mean to dereference a parameter passed in?
    # in that case, use ${$_[0]} = MY_CONST->{foo} and call some_method(\$var);
    $a = MY_CONST->{foo};
}

package Main;  # or any other namespace that isn't Foo...
# ...
my $b = Foo->MY_CONST->{baz}{innerbar};

1
谢谢,Ether。我会采用这种语法,因为它让我能够在任何地方一致地使用引用。我会将你的答案标记为被接受的答案,但是它来得有点晚了。 :) - Pistos
Hash::Util::lock_hash_recurse是一个不错的解决方案,但我更喜欢内置的解决方案。 - Dave Horner

8
您可以使用 Hash::Util 模块来锁定和解锁哈希表(键、值或两者皆可)。
package Foo;
use Hash::Util;

our %MY_CONST = (
    foo => 'bar',
    baz => {
        innerbar => 'bleh',
    }
);

Hash::Util::lock_hash_recurse(%MY_CONST);

接着在另一个文件中:

use Foo;
my $b = $Foo::MY_CONST{baz}{innerbar};

谢谢,Michael,这正是我所需要的。我试着使用lock_hashref,但似乎它对我来说没有被定义,但没关系,我可以用lock_hash来代替。 - Pistos
我注意到我可以仅通过“our”实现我所需的内容,我不需要Hash::Util。我不关心其他人在事后篡改哈希,我只是需要知道如何在Perl中定义一个可访问的常量。你的示例代码向我展示了如何做到这一点。 - Pistos
2
所以你真的不需要一个常量吗?Hash::Util 的东西是让人们无法更改哈希表的魔法。 - brian d foy
不,这是一个包变量。Perl没有“类变量”。 - jrockway

4

请查看 Readonly

#!/usr/bin/perl

package Foo;

use strict;
use warnings;

use Readonly;

Readonly::Hash our %h => (
    a => { b => 1 }
);

package main;

use strict;
use warnings;

print $Foo::h{a}->{b}, "\n";

$h{a}->{b} = 2;

输出:

C:\Temp> t
1
尝试修改只读值,位于 C:\Temp\t.pl 的第 21 行

我的系统上没有安装Readonly,并且我没有自由安装新模块的权限。但是感谢您的建议。当我在谷歌搜索时,我确实遇到了这个问题。 - Pistos
4
@Pistos http://perldoc.perl.org/perlfaq8.html#How-do-I-keep-my-own-module/library-directory%3F - Sinan Ünür
1
@Sinan:谢谢,但这对我的情况没有帮助。你可能把我的情况误认为是共享主机用户之类的。障碍不是技术上的,而是社会/政治/管理层面的。 :) - Pistos
@Pistos:他们相信你的脚本,对吧?你不需要搞乱系统中的 perl - Sinan Ünür

1

谢谢,虽然我通常在Perl中构建嵌套哈希。我的具体需求与在包/类内外使用它有关。 - Pistos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接