Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Changing the Class Name of a Moose Instance

by jandrew (Chaplain)
on Oct 03, 2012 at 15:37 UTC ( #997078=perlquestion: print w/replies, xml ) Need Help??
jandrew has asked for the wisdom of the Perl Monks concerning the following question:

I have been searching unsuccessfully for a way to change the class name of a Moose instance. Most specifically when I am composing Moose classes on the fly using Moose::Util 'with_traits'. Any helpful suggestions are appreciated.

The initial use case for me is to make the confess output from Carp more readable. I have included demonstration code below.

package MyClass; use Moose; has 'name' => ( is => 'ro', writer => 'set_name', predicate => 'has_name', ); no Moose; __PACKAGE__->meta->make_immutable; package Respect; use Moose::Role; use Carp qw( cluck ); sub get_respectful_name{ my ( $self, ) = @_; if( $self->has_name ){ return $self->name . " - San\n"; }else{ cluck "No name is available"; return undef } } no Moose::Role; use Moose::Util qw( with_traits ); use Smart::Comments '###'; my $business_associate = with_traits( 'MyClass', ( 'Respect', ), )->new(); print "Hello " . $business_associate->get_respectful_name . "\n"; $business_associate->set_name( 'Miyagi' ); print "Hello " . $business_associate->get_respectful_name . "\n"; 1;

The output is as follows

No name is available at line 22 Respect::get_respectful_name Moose::Meta::Class::__ANON__::SERIAL::1= HASH(0x3591540)') called at line 39 Use of uninitialized value in concatenation (.) or string at line 39. Hello Hello Miyagi - San

The goal would be to set -Moose::Meta::Class::__ANON__::SERIAL::1- to something more human readable.

It seems there might be other use cases for this but as a minimum the 'meta' capabilities of Moose have spoiled me into believing that all information about an instance is accessible and mutable as needed. I just can't seem to figure out how.

Update: spelling corrections

Replies are listed 'Best First'.
Re: Changing the Class Name of a Moose Instance
by tobyink (Abbot) on Oct 03, 2012 at 16:45 UTC
    use v5.14; use Moose (); sub with_traits_and_fancy_schmancy_name { my ($name, $base, @roles) = @_; return $base unless @roles; return 'Moose::Meta::Class'->create( $name, superclasses => [$base], roles => \@roles, )->name; } package Person { use Moose; has name => (is => 'ro', isa => 'Str'); sub add_numbers { my $self = shift; my $sum; $sum += $_ for @_; return $sum; } }; package Inumerate { use Moose::Role; around add_numbers => sub { confess "I'm no good at maths"; }; }; my $bob = with_traits_and_fancy_schmancy_name( 'Idiot', 'Person' => qw( Inumerate ), )->new(name => 'Robert'); $bob->add_numbers(1, 2, 3);

    Update: previously I didn't include a very good example usage.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Thanks++, that works.

      Update: I just ran the updated example and I like the 'confess' output that includes Idiot::add_numbers('Idiot=HASH(0x337cf38)', 1, 2, 3). Nice touch

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://997078]
Approved by davido
Front-paged by davido
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (4)
As of 2017-07-22 15:36 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (340 votes). Check out past polls.