Hatena::Groupcatalyst

dann@catalyst このページをアンテナに追加 RSSフィード

2008-05-01

Moose::Roleの使い方のサンプルp

Moose::Roleの使い方のサンプルp - dann@catalyst を含むブックマーク はてなブックマーク - Moose::Roleの使い方のサンプルp - dann@catalyst Moose::Roleの使い方のサンプルp - dann@catalyst のブックマークコメント

MooseのCookbookからRoleのInterfaceとしての役割を示すエッセンス部分を切り出してみました。

http://search.cpan.org/dist/Moose/lib/Moose/Cookbook/Recipe10.pod

#!/usr/bin/env perl
use strict;
use warnings;

{
    package Comparable;
    use Moose::Role;

    requires 'compare';

    sub equal_to {
        my ( $self, $other ) = @_;
        $self->compare($other) == 0;
    }
}

{
    package US::Currency;
    use Moose;

    with 'Comparable';

    has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );

    sub compare {
        my ( $self, $other ) = @_;
        $self->amount <=> $other->amount;
    }
}

my $currency10 = US::Currency->new(amount => 10);
my $currency20 = US::Currency->new(amount => 20);
my $other_currency10 = US::Currency->new(amount =>10);

warn $currency10->compare($currency20); #-1
warn $currency20->compare($currency10); #1
warn $currency10->equal_to($other_currency10); #1

Comparableというクラスが、Interfaceとしての役割を果たしていて、MooseのRoleになっています。このComparableを実装する人は、compareメソッドを実装しなければいけませんよというように読みます。(equal_toメソッドがcompareメソッドが実装されることを期待してます。)

Comparableを実装する具象クラスが、US::Currencyです。withというキーワードはMooseのキーワードで、JavaのImplementsみたいなものだと思ってください。要するに、このInterfaceを実装しますよということを明示します。このクラスで、compareメソッドを実装すると、equal_toメソッドも実装されます。

さて、これでcompareというメソッドを実装しない場合は、どうなるか試してましょう。compareをcompare2と名前を変えて、perl -wcでチェックすると、以下のようにcompare実装しろ!と怒られます。ちゃんと、Interfaceの役割として機能してますね。

'Comparable' requires the method 'compare' to be implemented by 'US::Currency'