<?xml version="1.0" encoding="windows-1252"?>
<node id="996029" title="Re: Altering the inheritance path of an object" created="2012-09-27 11:22:44" updated="2012-09-27 11:22:44">
<type id="11">
note</type>
<author id="757127">
tobyink</author>
<data>
<field name="doctext">
&lt;p&gt;Yes. The basic technique is to create a new package which inherits from the old one but adds some new methods, then rebless the object into that new package. Here's a quick example:&lt;/p&gt;

&lt;code&gt;
use 5.010;
use Math::BigInt;

# quite big!!
my $seven = Math::BigInt-&gt;new('7');

# $seven cannot "speak", so this warns
eval { $seven-&gt;speak } or warn $@;

{
	package Math::BigInt::Speaker;
	our @ISA = qw(Math::BigInt);
	use Scalar::Util qw(blessed);
	use Carp qw(confess);
	sub upgrade {
		my ($class, $instance) = @_;
		confess "can only upgrade Math::BigInt objects"
			unless blessed $instance &amp;&amp; $instance-&gt;isa('Math::BigInt');
		bless $instance =&gt; $class;
	}
	sub speak {
		CORE::say($_[0]);
	}
}

# Swaps $seven into our new class.
Math::BigInt::Speaker-&gt;upgrade($seven);

# $seven can now "speak"
eval { $seven-&gt;speak } or warn $@;
&lt;/code&gt;

&lt;p&gt;If you use [mod://Moose] you can do this in a much nicer and more organised way. (Though it's basically the same thing happening under the hood.) You'd just create a new anonymous role, and apply that role to the object.&lt;/p&gt;

&lt;code&gt;
use 5.010;
use Math::BigInt;
use Moose ();

# quite big!!
my $seven = Math::BigInt-&gt;new('7');

# $seven cannot "speak", so this warns
eval { $seven-&gt;speak } or warn $@;

my $speaker = Moose::Meta::Role-&gt;create_anon_role(
	methods =&gt; {
		speak =&gt; sub { CORE::say($_[0]) },
	},
);

Moose::Util::apply_all_roles($seven, $speaker);

# $seven can now "speak"
eval { $seven-&gt;speak } or warn $@;
&lt;/code&gt;

&lt;!-- Node text goes above. Div tags should contain sig only --&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-757127"&gt;
&lt;small&gt;&lt;small&gt;
&lt;tt&gt;perl -E'sub Monkey::do{say$_,for@_,do{($monkey=&amp;#x5B;caller(0)]-&gt;&amp;#x5B;3])=~s{::}{ }and$monkey}}"Monkey say"-&gt;Monkey::do'
&lt;/tt&gt;&lt;/small&gt;&lt;/small&gt;
&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
996022</field>
<field name="parent_node">
996022</field>
</data>
</node>
