http://www.perlmonks.org?node_id=1020341


in reply to any way to fill calling namespace with a "use Module"?

TIMTOWTDI, but I'd say the "official antlered" way to do it would perhaps be along these lines...

use v5.14; package Top { use Moose; has letter => ( is => 'ro', isa => Moose::Util::TypeConstraints::enum(['A', 'B']), required => 1, ); sub BUILD { my $self = shift; my $class = "Subordinate" . $self->letter; $class->meta->rebless_instance($self); } } package SubordinateA { use Moose; extends 'Top'; } package SubordinateB { use Moose; extends 'Top'; } print Top->new(letter => "B")->dump;

Of course, you can just use bless $object => $class to rebless an existing object into a different class. The Top class could do that somewhere in its constructor. (Though the Moose style is to not write constructors, but write BUILD/BUILDARGS methods instead!) However, the rebless_instance method is somewhat smarter - it allows you to pass in additional constructor parameters (in case the subordinate classes defined additional attributes), and checks that the class you're reblessing into is a subclass of the original class.

package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Replies are listed 'Best First'.
Re^2: any way to fill calling namespace with a "use Module"?
by blue_cowdawg (Monsignor) on Feb 23, 2013 at 21:56 UTC

    Wow! I didn't think of using BUILD that way. That's exactly what I'm looking for. (I'll write an experiment for this) Do you have to invoke use SubordinateA; use SubordinateB; in the invoking environment or ??? I suppose I can work around that...


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
      my $class = "Subordinate" . $self->letter; Class::Load::load_class($class);

      Class::Load is a dependency of Moose, so you're already using it.

      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name