他のハッシュを保存するのとほぼ同じ方法で、Moose オブジェクトにハッシュのハッシュを保存できます。
has steps => ( is => 'ro', isa => 'HashRef' );
ただし、そのスロットに保存されているものが正しい種類のものであることを確認する方法として、保存する必要がある特定の種類のハッシュとして宣言するように、より具体的にすることができます。
has steps => ( is => 'ro', isa => 'HashRef[HashRef[Object]]' );
データによっては、Object
ここでもクラス名に変更する場合があります。MooseX::TypesとMooseX::Types::Structuredを使用して、さらに厳密な構造を指定することもできます。
あなたの構造をまたぐヘルパーについては、私は Moose や MooseX でそれを行うものを知りません。データの構造を知っている場合は、サブルーチンを実装して必要なことを自分で行うのがおそらく最善です。あなたのコードは、一般的なトラバーサルよりも優れたパフォーマンスを発揮し、必要なことを実行する可能性があります。
編集/追加情報:各 Moose 属性は、保存された値を返すクラスのアクセサ メソッドを作成するため、データへのアクセスは次のとおりです。
# 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
}
}
もう 1 つ注意traits => [ 'Hash' ]
してください。必要に応じて、いくつかのハンドルを使用および追加して、追加のヘルパーを自分自身に与えることができます。
データ構造がそれよりも自由な形式である場合は、Data::Visitorのようなものを調べて、サブルーチンで構造を反復処理することをお勧めします。(Data::Visitor でデバッグが困難で奇妙な問題が発生したことがあるので、できる限り回避するようにしています。)