in reply to Moose question
There is no simple way to do what you ask and still be able to define the attributes as you currently are. This is obviously because Moose is managing the instance data structure for you. What you really want is a sub-object, but ...
I think I could do this by creating a new class with these various attributes in it, but I don't want to do that for a number of reasons.
What might those reasons be? Because what your looking to do is exactly that, encapsulate all these items into a sub-object. You could even us a combination of delegation and coercion to make it seem like you aren't using a sub-object at all.
The above code would allow you do things like:package My::New::OptionObject; use Moose; use Moose::Util::TypeConstraints; coerce 'My::New::OptionObject' from 'HashRef' via { My::New::OptionObject->new( %{ $_ }) }; has max_chunk => ( is=>'rw', isa=>'Int', init_arg => 'size', clearer=>'clear_max_chunk' ); has liberal_mode => ( is=>'rw', isa=>'Bool', default=>sub{1} ); has fh => ( is=>'rw', isa=>'My::New::Object::ProtoFileHandle', clearer=>'clear_fh', predicate=>'has_fh', writer=>'_set_fh', coerce => 1, init_arg => 'file', trigger => \&reset_temporary_variables ); package My::New::Object; use Moose; has options => ( is => 'ro', writer => 'set_all_options', isa => 'My::New::OptionObject', handles => [qw[ max_chunk liberal_mode fh ]], # and any others you + might want ... coerce => 1, lazy => 1, clearer => 'clear_options', default => sub { My::New::OptionObject->new } );
This will coerce the options HASH into a My::New::OptionObject for you, and because of the delegation you can still call the max_chunk, liberal_mode and fh accessor methods on $o.my $o = My::New::Object->new( options => { ... pass in the args to the options here ... } );
This will clear the instance of My::New::OptionObject and because of default and lazy are there, the next time you try and call a method on it it will create a new (empty) My::New::OptionObject object.$o->clear_options;
Since the option attribute's writer is called "set_all_options" and coerce is on, this will just work and create a new My::New::OptionObject object for you.$o->set_all_options( { ... } );
So while you can't do exactly what your looking for in terms of changing the instance structure, we can "fake" it to some degree, which should be sufficient since you should be treating your objects as black boxes anyway :)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Moose question
by gwg (Beadle) on Aug 28, 2009 at 22:52 UTC |