On Sat, Apr 18, 2009 at 7:58 PM, Fayland Lam <[email protected]> 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