Setting delegated attributes in constructors
I'd like to set delegated attributes in my object constructors (e.g. as below) but this doesn't seem to work. Am I missing something? Merlyn #!/usr/bin/perl package SubClass; use Moose; has thing => ( is => 'rw', isa => 'Int' ); before thing => sub { shift; print "subthing: ", @_ ? 'set to ' . (shift // '') : '(read)', "\n"; return; }; package Class; use Moose; has sub_object => ( is => 'rw', isa => 'SubClass', handles => ['thing'], builder => '_build_sub_object' ); #has sub_object => ( is => 'rw', isa => 'SubClass', handles => ['thing'], default => sub { _build_sub_object(); } ); sub _build_sub_object { my $self = shift; print "_build_sub_object\n"; return SubClass->new; } package main; use strict; use warnings; print "Start\n"; my $object = Class->new(thing => 1); print "Built\n"; print "Thing 1 = ", ($object->thing // ''), "\n"; $object->thing(2); print "Thing 2 = ", ($object->thing // ''), "\n"; -- -- Merlyn
Re: Setting delegated attributes in constructors
Thanks for quick and helpful replies. I'm not really trying to subvert inheritance though I now see that my simplified example looks much like that. I'd contemplated the BUILD(ARGS) route but couldn't see exactly how to do it without losing some of the validation benefits (again, not really visible in my simplified example). In my real code the composed in object that I'm trying to delegate to is actually a lazily built DBIx result object, FWIW. I guess the problem here is that Moose doesn't really call the accessors in the constructor but just uses some shortcut to copy the constructor parameters to the object. I think I'll look for a different solution. Or just stick with what I've got now, where I call the accessors immediately after construction. Looks ugly but there you go. Thanks again, Merlyn On Tue, 13 Feb 2018 at 16:18 Harald Jörg <harald.jo...@arcor.de> wrote: > Merlyn Kline <mer...@binary.co.uk> writes: > > > I'd like to set delegated attributes in my object constructors > > (e.g. as below) but this doesn't seem to work. Am I missing > > something? > > perldoc Moose::Manual::Delegation calls it "Attribute delegation", but > actually you're not delegating attributes. Instead, you are delegating > method calls to an attribute of your class. > > So this is what you are missing: Calling Class->new simply isn't calling > $object->thing underneath. If you add MooseX::StrictConstructor to your > package Class, it will barf at you saying > >Found unknown attribute(s) init_arg passed to the constructor: thing > > BUILD or BUILDARGS can help to achieve what you're trying to do. > -- > Cheers, > haj > -- -- Merlyn