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.

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 } );
The above code would allow you do things like:
my $o = My::New::Object->new( options => { ... pass in the args to the options here ... } );
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.
$o->clear_options;
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->set_all_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.

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 :)

-stvn

In reply to Re: Moose question by stvn
in thread Moose question by gwg

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.