On Wed, Mar 02, 2011 at 11:36:07AM -0600, Mark A. Stratman wrote: > On Mar 2, 2011, at 9:23 AM, matthew couchman (JIC) wrote: > > I'd like to subclass a non moose class Math::VectorReal so that I can do > > this > > > But its not working, I guess because of the first caveat on the manual page > > that says that references must be the same between the moose class and the > > non-moose class. I'm a bit lost to be honest, could someone point me in > > the right direction? > > The problem is that Math::VectorReal uses an arrayref for its internal > structure. It does a bless([] ...), but MooseX::NonMoose likes hashrefs. > I think MooseX::NonMoose::InsideOut should take care of it. Something like > this:
Yes, MooseX::NonMoose::InsideOut is the right answer here. > package BetterVector; > use Moose; > use MooseX::NonMoose::InsideOut; # NOTE - different module > use namespace::autoclean; > extends 'Math::VectorReal'; > > has [qw(x y z)] => ( > isa => 'Num', > is => 'ro', # NOTE - 'ro', not 'rw'.... more on this below > ); > > sub FOREIGNBUILDARGS { > my ($class, %vals) = @_; > return map { $vals{$_} } qw(x y z); # NOTE - Math::VR requires args in a > specific order, but WE shouldn't. > } > > no Moose; > > package main; > use Modern::Perl; > my $v = BetterVector->new(x => 1, y => 2, z => 0.5); > say $v->length; But you don't want to do it this way, really... overriding the attributes that already exist in Math::VectorReal isn't useful, and will cause issues (as mentioned). Something like this should be sufficient: package BetterVector; use Moose; use MooseX::NonMoose::InsideOut; use namespace::autoclean; extends 'Math::VectorReal'; # don't declare x, y, and z as moose attrs # (but you can declare other attrs if you want) # and make sure moose doesn't see them when they come into the # constructor around BUILDARGS => sub { my $orig = shift; my $class = shift; my $args = $class->$orig(@_); delete $args->{$_} for qw(x y z); $args; }; # and then this is the same sub FOREIGNBUILDARGS { my $class = shift; my %vals = @_; return map { $vals{$_} } qw(x y z); } no Moose; 1; This way, Math::VectorReal is still handling the things it knows about on its own, and you can add new attributes beyond those if you want in a way that doesn't interfere with anything it's doing. -doy