如何存储哈希值的散列驼鹿?(How to store Hash of Hashes in Moose

2019-07-30 18:03发布

我想知道,什么是存储哈希值的哈希在穆斯的最佳途径。 让我们例如哈希是这样的:

my %hash = ('step1' => {'extraction' => \$object1,
                         'analysis' => \$object2},
            'step2' => {'extraction' => \$object3,
                         'analysis' => \$object4});

但我想保存此一个在驼鹿属性。 我应该如何组织这一访问(读,写)。 在网络上的例子是大多为“平”的哈希值。 但是,那么你可以使用像驼鹿::元::属性::本地::特质::哈希帮手。 是否有哈希散列类似的东西?

原因是,我想迭代步骤,密钥和访问该对象的实例。 还是有更好,更驼鹿般的方式做到这一点?

提前致谢!!!

Answer 1:

您可以存储哈希散列在相当多,你会存储任何其他哈希以同样的方式驼鹿对象:

has steps => ( is => 'ro', isa => 'HashRef' );

你可以,但是,更具体到其声明为特定种类的哈希,你需要存储的方式来验证存储在插槽什么是正确的那种东西:

has steps => ( is => 'ro', isa => 'HashRef[HashRef[Object]]' );

根据数据,我也可能会改变Object这里的类名。 你可以得到更炫,并使用MooseX ::类型和MooseX ::种类::结构来指定一个更加严格的结构。

至于佣工步骤在你的结构,我不知道在穆斯或MooseX什么做到这一点。 如果你知道你的数据的结构,它可能是最好只执行一个子程序做什么,你需要自己。 您的代码可能会表现得更好,做你需要比任何通用遍历更好。

编辑/其它信息:每个驼鹿属性创建的存取方法没有你的类返回所存储的值,所以访问该数据是:

# Assuming we put the attribute in a package named StepTool
my $step_tool = StepTool->new(
    steps => { 'step1' => {'extraction' => \$object1,
                             'analysis' => \$object2},
               'step2' => {'extraction' => \$object3,
                             'analysis' => \$object4} },
);

# To do something one of the values
do_something($step_tool->steps->{step1}{extraction});

# To iterate over the structure, could be done in a method on StepTool
for my $step_name (keys %{ $step_tool->steps }) {
    my $step = $step_tool->steps->{ $step_name };

    for my $action_name (keys %$step) {
        my $object = $step->{ $action_name };

        do_something($object);
    }
}

# If doing the above as a method, $self is the Moose object, so...
sub traverse_steps {
    my ($self) = @_;

    for my $step_name (keys %{ $self->steps }) {
        ... # just like above
    }
}

和另外一个音符,你仍然可以使用traits => [ 'Hash' ]并添加一些把手给自己一些额外的帮手,如果你想要的。

如果数据结构是更自由的形式比,你可能想看看像数据::游客来遍历你的子程序的结构。 (我有一些难以调试,使用数据::游客怪异的问题,所以我尽量避免它,当我可以。)



Answer 2:

还有灵感类型安全的方法穆斯:如何获取对象的数组? 特点?

还有一类,以容纳具有外散列(StepTool ::步骤) traits => ['Hash'] 这种方法可以无限深例如使用嵌套Array S和Hash ES:

package StepTool;

use Moose;

has 'steps' => (
    'is' => 'rw',
    'isa' => 'StepTool::Steps',
    'default' => sub { StepTool::Steps->new() },
);

package StepTool::Steps;

use Mouse;

has '_steps' => (
    is => 'ro',
    isa => 'HashRef[StepTool::Step]',
    traits => ['Hash'],
    default => sub { {} },
    handles => {
        # You'll probably want a fuller set here...
        get => 'get',
        set => 'set',
        keys => 'keys',
    }
);

package StepTool::Step;

use Mouse;

has 'extraction' => (
    is => 'rw',
);

has 'analysis' => (
    is => 'rw',
);

package main;

my $object1 = bless {}, 'Foobar1';
my $object2 = bless {}, 'Foobar2';
my $object3 = bless {}, 'Foobar3';
my $object4 = bless {}, 'Foobar4';

my $stepTool = StepTool->new();

# set up step1 one field at a time.
$stepTool->steps->set('step1', StepTool::Step->new());
# I have no idea why the OP wants references to objects
# everywhere but he does...
$stepTool->steps->get('step1')->extraction(\$object1);
$stepTool->steps->get('step1')->analysis(\$object2);

# set up step2 all at once
$stepTool->steps->set('step2', StepTool::Step->new(
    extraction => \$object3,
    analysis => \$object4
));

# or, less elegantly, initialize an entire StepTool:
my $stepTool2 = StepTool->new(
    steps => StepTool::Steps->new(
        _steps => {
            step1 => StepTool::Step->new(
                extraction => \$object1,
                analysis => \$object2
            ),
            step2 => StepTool::Step->new(
                extraction => \$object3,
                analysis => \$object4
            ),
        }
    ),
);

printf "step1->analysis is a ref to an instance of class: %s\n",
    ref(${$stepTool->steps->get('step1')->analysis});


文章来源: How to store Hash of Hashes in Moose?