http://www.perlmonks.org?node_id=1072264


in reply to [Moose] Critique request on my Moose design (anti?)pattern

I use Moose a lot and can probably help you, but I'm not sure I understand your question.

You said: ...needing "sub" objects regularly. What is a "sub" object to you? What I see in your code is that MyApp (My::App object) is an attribute of the "My" class. Is that what you call a sub object?

Also: How do you deal with passing required attributes through? ... You mean through the "sub" object? If you want to pass your required attributes from the "My" object to the "MyApp" attribute, I recommend using a "lazy" attribute with a "builder". Try this (you can get fancy later):

has 'MyApp' => ( lazy => 1, isa => 'My::App', builder => '_build_myapp', ); sub _build_myapp { my $self = shift; return My::App->new( foo => $self->app_foo, bar => $self->app_bar, ); };

It's much cleaner.

A for will get you from A to Z; a while will get you everywhere.

Replies are listed 'Best First'.
Re^2: [Moose] Critique request on my Moose design (anti?)pattern
by three18ti (Monk) on Feb 01, 2014 at 08:27 UTC

    Hey thanks for the reply.

    For instance, if I'm building a Car object, I'll probably want to declare an "Engine" object and then handle the delegation of that objects methods in the Car object.

    E.g.:

    package Car::Engine; use 5.010; use Moose; use strict; use warnings; has [qw(cylinder rpm fuel)] { is => 'rw', isa => 'Int', } sub get_rpm { my $self = shift; my $curr_rpm = $self->rpm / $self->cylinder; } package Car; use 5.010; use Moose; use strict; use warnings; has [qw(engine_cylinder engine_rpm engine_fuel)] => ( is => 'rw', isa => 'Int', ); has engine => ( is => 'rw', isa => 'Car::Engine', default => { Car::Engine->new( cylinder => $_[0]->engine_cylinder, rpm => $_[0]->engine_rpm, fuel => $_[0]->engine_rpm, ); }, handles => { get_rpm => 'get_rpm', } ); package main; use 5.010; use strict; use warnings; my $car = Car->new( engine_cylinder => '8', engine_rpm => '8000', engine_fuel => '1000', ); say $car->get_rpm;

    (actually, the equation for rpms doesn't make any sense, but it was just to show that ->get_rpm is different than ->rpm)

    In the real world I'm working on a library to manage VMs and I've created several objects to represent things like the Hypervisor Cluster and the VM (which represents all the attributes for the vm, the actual running vm is then represented by a different object which I'm trying to figure out how to handle).

    I don't know what the correct term for "Car::Engine" would be in this case which is why I called it a "sub-object" in my previous comment.

    I just seem to be using the pattern a lot which results is a lot of duplicate typing (or cut and paste) which got me to thinking maybe there's a better way to go about using objects in my primary (in this case "Car") object.