tags:

views:

102

answers:

1

What is the correct way to create an instance from another Moose object? In practice I've seen this done numerous ways:

$obj->meta->name->new()
$obj->new()  ## which has been deprecated and undeprecated
(blessed $obj)->new()
-- and, its bastard variant: (ref $obj)->new()
$obj->meta->new_object()

And, then what if you have traits? Is there a transparent way to support that? Do any of these work with anonymous classes?

+4  A: 

Of your choices, $obj->meta->name->new() or (blessed $obj)->new() are both the safest.

The way traits are implemented, you create an anonymous subclass and apply the roles to that subclass and rebless the instance into that subclass. This means that either of these solutions will work fine with traits. Perl lacks truly anonymous subclasses (every package has to have namespace), Moose works around this by creating a name in a generic namespace for anonymous classes.

If you'd taken a second to try some example code, you'd see this in action.

  $perl -Moose -E'with q[MooseX::Traits];
  package Role; use Moose::Role;
  package main; say Class->with_traits(q[Role])->new->meta->name'

  MooseX::Traits::__ANON__::SERIAL::1

Hope that helps.

perigrin