Moose attribute subclassing
User:
mcholste
Date: 12/6/2012 11:17 am
Date: 12/6/2012 11:17 am
Views: 556
Rating: 0
Rating: 0
Here's a simple question:
I've got a parent Moose class we'll call:
has 'thing' => (is => 'rw', isa => 'HashRef', required => 1, default => sub { { a => 1 } });
Then in the child class I want to add to this default hashref so that calling Child->thing produces { a => 1, b => 2 }. This doesn't work:
has '+thing' => (default => sub { { b => 2 } });
Because it just replaces the parent's default. I want to add to it. Ideas? I can obviously handle this in BUILD, but I was hoping to do this with Moose Magic (TM).
I've got a parent Moose class we'll call:
has 'thing' => (is => 'rw', isa => 'HashRef', required => 1, default => sub { { a => 1 } });
Then in the child class I want to add to this default hashref so that calling Child->thing produces { a => 1, b => 2 }. This doesn't work:
has '+thing' => (default => sub { { b => 2 } });
Because it just replaces the parent's default. I want to add to it. Ideas? I can obviously handle this in BUILD, but I was hoping to do this with Moose Magic (TM).
Re: Moose attribute subclassing
User:
hoelzro
Date: 12/6/2012 11:35 am
Date: 12/6/2012 11:35 am
Views: 0
Rating: 0
Rating: 0
I would use a builder and around.
–Rob
mcholste@gmail.com wrote:
mcholste wrote:
Here's a simple question:
I've got a parent Moose class we'll call:
has 'thing' => (is => 'rw', isa => 'HashRef', required => 1, default => sub { { a => 1 } });
Then in the child class I want to add to this default hashref so that calling Child->thing produces { a => 1, b => 2 }. This doesn't work:
has '+thing' => (default => sub { { b => 2 } });
Because it just replaces the parent's default. I want to add to it. Ideas? I can obviously handle this in BUILD, but I was hoping to do this with Moose Magic (TM).
Madison Area Perl Mongers - MadMongers
http://www.madmongers.org
--
Sent from Kaiten Mail. Please excuse my brevity.
Re: Moose attribute subclassing
User:
theraccoonbear
Date: 12/6/2012 11:45 am
Date: 12/6/2012 11:45 am
Views: 112
Rating: 0
Rating: 0
I'm new to tinkering with Moose, but here's what I just threw together. I'm sure this is not the most sensible way to do this, but it works...
ParentClass.pm
has 'someHashRef' => (
is => 'rw',
isa => 'HashRef',
default => sub {
return {
a => 1
};
}
);
ChildClass.pm (extends ParentClass)
has 'someHashRef' => (
is => 'rw',
isa => 'HashRef',
default => sub {
my $pc = ParentClass->new();
return { %{$pc->someHashRef}, %{{b => 2}}};
}
);
Re: Moose attribute subclassing
User:
mcholste
Date: 12/6/2012 2:42 pm
Date: 12/6/2012 2:42 pm
Views: 104
Rating: 0
Rating: 0
That works, but only if you don't want to pass arguments to the parent class, right? My actual class has some mandatory parameters.
Rob's "around' method doesn't work because the around-iness isn't inherited, so grandchild classes don't pick up the change. At least as far as I can tell, please let me know if I'm wrong there.
Rob's "around' method doesn't work because the around-iness isn't inherited, so grandchild classes don't pick up the change. At least as far as I can tell, please let me know if I'm wrong there.
On Thu, Dec 6, 2012 at 11:45 AM, <don.c.smith@gmail.com> wrote:
theraccoonbear wrote:
I'm new to tinkering with Moose, but here's what I just threw together. I'm sure this is not the most sensible way to do this, but it works...ParentClass.pmhas 'someHashRef' => (is => 'rw',isa => 'HashRef',default => sub {return {a => 1};});ChildClass.pm (extends ParentClass)has 'someHashRef' => (is => 'rw',isa => 'HashRef',default => sub {my $pc = ParentClass->new();return { %{$pc->someHashRef}, %{{b => 2}}};});
Re: Moose attribute subclassing
User:
theraccoonbear
Date: 12/6/2012 3:18 pm
Date: 12/6/2012 3:18 pm
Views: 0
Rating: 0
Rating: 0
Again, I'm a Moose novice, and I know you said Rob's around recommendation doesn't work for you, but wouldn't around BUILDARGS allow you to store the constructor arguments?
if you save what's in @_ you should be able to pass those on to the parent class constructor then, right?
my @saved_for_later;
around BUILDARGS => sub {
@saved_for_later = @_;
};
has 'someHashRef' => (
is => 'rw',
isa => 'HashRef',
default => sub {
my $pc = ParentClass->new(@saved_for_later);
return { %{$pc->someHashRef}, %{{b => 2}}};
}
);
Sorry if I'm just showcasing my ignorance here.
--
Don Smith
don.c.smith@gmail.com
"and don't tell me there isn't one bit of difference between null and space, because that's exactly how much difference there is." Larry Wall
--
Don Smith
don.c.smith@gmail.com
"and don't tell me there isn't one bit of difference between null and space, because that's exactly how much difference there is." Larry Wall
On Thu, Dec 6, 2012 at 2:42 PM, <mcholste@gmail.com> wrote:
mcholste wrote:
That works, but only if you don't want to pass arguments to the parent class, right? My actual class has some mandatory parameters.
Rob's "around' method doesn't work because the around-iness isn't inherited, so grandchild classes don't pick up the change. At least as far as I can tell, please let me know if I'm wrong there.
On Thu, Dec 6, 2012 at 11:45 AM, <don.c.smith@gmail.com> wrote:theraccoonbear wrote:
I'm new to tinkering with Moose, but here's what I just threw together. I'm sure this is not the most sensible way to do this, but it works...ParentClass.pmhas 'someHashRef' => (is => 'rw',isa => 'HashRef',default => sub {return {a => 1};});ChildClass.pm (extends ParentClass)has 'someHashRef' => (is => 'rw',isa => 'HashRef',default => sub {my $pc = ParentClass->new();return { %{$pc->someHashRef}, %{{b => 2}}};});
Re: Moose attribute subclassing
User:
hoelzro
Date: 12/6/2012 3:23 pm
Date: 12/6/2012 3:23 pm
Views: 0
Rating: 0
Rating: 0
The following *should* work (untested):
package Parent {
use Moose;
has someHashRef => (
is => 'ro',
builder => '_build_hash_ref',
);
sub _build_hash_ref {
return { a => 1 };
}
}
package Child {
use Moose;
extends 'Parent';
around _build_hash_ref => sub {
my ( $orig, $self ) = @_;
return { %{ $orig->($self) }, b => 2 };
};
}
package Grandchild {
use Moose;
extends 'Child';
around _build_hash_ref => sub {
my ( $orig, $self ) = @_;
return { %{ $orig->($self) }, c => 3 };
};
}
As long as you're diligent about using around in subclasses rather than re-defining _build_hash_ref, that is.
On 12/6/12 9:42 PM, mcholste@gmail.com wrote:
package Parent {
use Moose;
has someHashRef => (
is => 'ro',
builder => '_build_hash_ref',
);
sub _build_hash_ref {
return { a => 1 };
}
}
package Child {
use Moose;
extends 'Parent';
around _build_hash_ref => sub {
my ( $orig, $self ) = @_;
return { %{ $orig->($self) }, b => 2 };
};
}
package Grandchild {
use Moose;
extends 'Child';
around _build_hash_ref => sub {
my ( $orig, $self ) = @_;
return { %{ $orig->($self) }, c => 3 };
};
}
As long as you're diligent about using around in subclasses rather than re-defining _build_hash_ref, that is.
On 12/6/12 9:42 PM, mcholste@gmail.com wrote:
mcholste wrote:
That works, but only if you don't want to pass arguments to the parent class, right? My actual class has some mandatory parameters.
Rob's "around' method doesn't work because the around-iness isn't inherited, so grandchild classes don't pick up the change. At least as far as I can tell, please let me know if I'm wrong there.
On Thu, Dec 6, 2012 at 11:45 AM, <don.c.smith@gmail.com> wrote:
theraccoonbear wrote:
I'm new to tinkering with Moose, but here's what I just threw together. I'm sure this is not the most sensible way to do this, but it works...
ParentClass.pm
has 'someHashRef' => (is => 'rw',isa => 'HashRef',default => sub {return {a => 1};});
ChildClass.pm (extends ParentClass)
has 'someHashRef' => (is => 'rw',isa => 'HashRef',default => sub {my $pc = ParentClass->new();return { %{$pc->someHashRef}, %{{b => 2}}};});
Madison Area Perl Mongers - MadMongers
http://www.madmongers.org
Re: Moose attribute subclassing
User:
mcholste
Date: 12/6/2012 3:54 pm
Date: 12/6/2012 3:54 pm
Views: 0
Rating: 0
Rating: 0
Yes, this works as advertised, so I think it's probably the best solution. I was neglecting the features that "builder" provides. Thanks, all!
On Thu, Dec 6, 2012 at 3:23 PM, <rob@hoelz.ro> wrote:
package Parent {
use Moose;
has someHashRef => (
is => 'ro',
builder => '_build_hash_ref',
);
sub _build_hash_ref {
return { a => 1 };
}
}
package Child {
use Moose;
extends 'Parent';
around _build_hash_ref => sub {
my ( $orig, $self ) = @_;
return { %{ $orig->($self) }, b => 2 };
};
}
package Grandchild {
use Moose;
extends 'Child';
around _build_hash_ref => sub {
my ( $orig, $self ) = @_;
return { %{ $orig->($self) }, c => 3 };
};
}