Yet another native traits in Moose
id:tokuhiromの示唆を得て,Native traits/AttributeHelpersについて考えてみた。
現在MooseではMX::AttributeHelpersが"Native traits"として組み込みになっているが,それにもかかわらずhas()の時点でtraits => ['Array']などとしないと使用できない。これは冗長だ。
use Any::Moose; has foo => ( is => 'ro', isa => 'ArrayRef', traits => ['Array'], # 冗長 handles => { # ... }, );
"isa"でArrayRefを指定しているのだから,traits => ['Array']は明らかに冗長である。
ところで,native traitsの仕組みは委譲の一種と考えることができる。その方向で考えると,既存のMooseの委譲メカニズムでこれに近いことができることに気づく。
#!perl -w use 5.010; package My::HashRef; use Any::Moose; sub store{ my($hashref, $key, $value) = @_; $hashref->{$key} = $value; } sub keys{ my($hashref) = @_; return keys %{$hashref}; } package Foo; use Any::Moose; has map => ( is => 'ro', isa => 'My::HashRef', default => sub{ My::HashRef->new }, handles => { map_keys => 'keys', map_store => 'store', }, ); package main; my $foo = Foo->new(); $foo->map_store(hoge => 42); $foo->map_store(fuga => 43); say $foo->dump; say join ' ', $foo->map_keys; # => fuga hoge __END__
もちろん,今はこれをオブジェクトに対してしか行えないので,たとえば,isa => 'Str'などとすることはできない。このあたりをもう少し詰めれば,委譲メカニズムのちょっとした拡張でtraitsの指定を省略することができるかもしれない。