Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to instantiate a Moose object from another Moose object?

Tags:

perl

moose

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?

like image 547
NO WAR WITH RUSSIA Avatar asked Jul 14 '10 21:07

NO WAR WITH RUSSIA


1 Answers

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.

like image 69
perigrin Avatar answered Oct 20 '22 05:10

perigrin