On Sat, Apr 18, 2009 at 7:58 PM, Fayland Lam <fayl...@gmail.com> wrote:
> well, my final solution is
>
> package Test;
>
> use Moose;
>
> sub new {
>    my $class = shift;
>    my $params = $class->BUILDARGS(@_);
>
>    my $obj;
>    if ( $params->{ver} == 1 ) {
>        require T::V1;
>        $obj = T::V1->new($params);
>    } else {
>        require T::V2;
>        $obj = T::V2->new($params);
>    }
>
>    return $class->meta->new_object(
>        __INSTANCE__ => $obj,
>       �...@_,
>    );
> }
>
> any comment are welcome. Thanks.
>

Sorry I've been really busy all weekend and not at a computer. Your
problem is what people in other situations call a Factory Pattern with
a minor variation. I meant to write a while ago (like I said busy) a
suggestion of something like:

package Test;
use Moose;

has version => ( isa => 'Str', required => 1);
has instance => ( isa => 'Test::V1|Test::V2, lazy_build => 1, handles
=>['ver']);
sub _build_instance { $class = "Test::${\$_[0]->version}"; $class->new() };


then in your main class:
print Test->new(version => 'V1')->ver; # prints 1
print Test->new(version => 'V2')->ver; # prints 2

this is slightly cleaner than messing with the MOP's instance stuff
and *much* more explicit about what is happening. When you scale past
single methods and single versions you can move to an interface Role
and change your instance definition to:

has instance => ( does => 'Test::Interface', handles =>
'Test::Interface', lazy_build => 1);

Then make sure that all your "Version" objects does() Test::Interface.

-Chris

Reply via email to