MooseX::AttributeHelpersでArrayRef、HashRefのアクセッサを簡単に作成する

Moose標準だと、ArrayRefのattributeを作ってそれをラップするメソッドを書く事になりますが、これは面倒です。そんなときに、使うのがMooseX::AttributeHelpersです。

attributeを拡張してくれます。これで、arrayrefにaliasのようなものを追加できるようになります。以下は、urlsのaccessorにurlをaddするメソッドを提供する例です。

providesに書いたadd_urlというメソッドがarray refのpushに対応します。HashRefなども同様の形で簡単に追加できるので、array, hashへのラッパメソッドを書いている人は、これを使ってみるといいかと思います。

ArrayRefの場合

#!/usr/bin/env perl
use Data::Dumper;

{
  package Crawler;
  use Moose;
  use MooseX::AttributeHelpers;

  has 'urls' => (
      metaclass => 'Collection::Array',
      is        => 'ro',
      isa       => 'ArrayRef[Str]',
      default   => sub { [] },
      provides  => {
          'push' => 'add_url',
      }   
  );  
}

my $crawler = Crawler->new;
$crawler->add_url('http://www.google.co.jp');
$crawler->add_url('http://www.yahoo.co.jp');

warn Dumper $crawler->urls;

実行結果

$VAR1 = [
          'http://www.google.co.jp',
          'http://www.yahoo.co.jp'
        ];

HashRefの場合

#!/usr/bin/env perl
use Data::Dumper;
use Perl6::Say;

{
  package Stuff;
  use Moose;
  use MooseX::AttributeHelpers;
  
  has 'options' => (
      metaclass => 'Collection::Hash',
      is        => 'ro',
      isa       => 'HashRef[Str]',
      default   => sub { {} },
      provides  => {
          'set'    => 'set_option',
          'get'    => 'get_option',            
          'empty'  => 'has_options',
          'count'  => 'num_options',
          'delete' => 'delete_option',
      }
  );
}

my $stuff = Stuff->new;
$stuff->set_option('option1' => 'value1');
$stuff->set_option('option2' => 'value2');

say 'option1 value: ' . $stuff->get_option('option1');
say Dumper $stuff->options;

$stuff->delete_option('option1');
say Dumper $stuff->options;

say 'option nums: ' . $stuff->num_options;
say 'has option?: ' . $stuff->has_options('option2');

実行結果

option1 value: value1
$VAR1 = {
          'option1' => 'value1',
          'option2' => 'value2'
        };

$VAR1 = {
          'option2' => 'value2'
        };

option nums: 1
has option?: 1