Dear monks,

I'd like to ask you for an advice regarding attribute accessors' naming.

I started to develop a project that is supposed to have quite a ramified hierarchy of classes, for example, the `SomeFramework` class, a bunch of classes like `SomeFramework::Logger` and, let's say, classes similar to `SomeFramework::SomeSubsystem::SomeComponent::SomeAPI` classes.

My goal is to design the most efficient communication between all these classes. I'll explain how I'm doing it now, so maybe you would like to share some opinions on how to make it better.

When I initialize the `SomeFramework` class, I have an object reference which I use from my application.

my $someframework = SomeFramework->new(parameter => 'value');

The `SomeFramework` class has some attributes, such as `logger`, `configuration`, etc, here are some examples of their definitions:

has 'logger' => ( is => 'ro', isa => 'SomeFramework::Logger', reader => 'get_logger', writer => '_set_logger', builder => '_build_logger', lazy => 1 ); sub _build_logger { my $self = shift; SomeFramework::Logger->new(someframework => $self); }

I'm passing the reference to the parent object to the child object, because I need the child to have access to the parent and its methods & accessors. So in the `SomeFramework::Logger` I have such attribute:

has 'someframework' => ( is => 'ro', isa => 'SomeFramework', reader => 'get_someframework', writer => '_set_someframework', required => 1 );

It lets me to have access to any object from within the `SomeFramework::Logger` class, usually it looks something like that:

my $configuration = $self-> get_someframework-> get_configuration-> get_blah_blah;

To extrapolate it, let's look into the `SomeFramework::SomeSubsystem::SomeComponent::SomeAPI` class. This class has its own "parent" attribute (let's call it `somecomponent`) which is supposed to have a reference to a `SomeFramework::SomeSubsystem::SomeComponent` object as the value. The `SomeFramework::SomeSubsystem::SomeComponent` class has the attribute for its own parent attribute (we can call it `somesubsystem`) which is supposed to contain a reference to a `SomeFramework::SomeSubsystem` object. And, finally, this class has the attribute for its own parent too (`someframework`), so it contains the reference to a `SomeFramework` object.

It all makes it possible to have something like that inside of the `SomeFramework::SomeSubsystem::SomeComponent::SomeAPI` class:

my $configuration = $self-> get_someframework-> get_somesubsystem-> get_somecomponent-> get_configuration-> get_blah_blah;

The first thing I'd like to know: is it a good practice? I hope, it is, but maybe you would advice me to go some more smooth way?

The second question is a bit more complicated (as for me), but I hope you'll help me with it. :) I like canonical names of accessors recommended by D.Conway in his "Perl Best Practices", but I'd like to do something like that:

my $configuration = $self->sc->ss->sf->conf->blah_blah;

Surely I can name all readers in this laconical manner:

has 'some_framework' => ( is => 'ro', isa => 'SomeFramework', reader => 'sf', writer => '_set_someframework', required => 1 );

But I don't like the idea of managing without the "standard" accessors names. :(

Also I can use `MooseX::Aliases`, it works fine for something like that:

has 'some_framework' => ( is => 'ro', isa => 'SomeFramework', reader => 'get_someframework', writer => '_set_someframework', required => 1, alias => 'sf' );

It looks fine, but there's an issue with attributes which names do NOT needed to be shortened. For example:

has 'api' => ( is => 'ro', isa => 'SomeFramework::API', reader => '_get_api', writer => '_set_api', required => 1, alias => 'api' );

In this case Moose throws an exception: `Conflicting init_args: (api, api) at constructor`. :( As I understand, MooseX::Aliases tries to create an attribute with the same value of the `init_args` parameter, so it fails. By the way, sometimes it happens, but sometimes it works fine, I haven't discovered when exactly it doesn't work.

Maybe I should have something like that:

has 'api' => ( is => 'ro', isa => 'SomeFramework::API', reader => '_get_api', writer => '_set_api', required => 1, handles => { api => 'return_self' # ^^^ It's supposed to have some method that # returns the reference to its own object } );
? But it doesn't seem to be the best option too, because it helps me only if the attribute contains a reference some object for which I can define the `return_self` method. If the attribute contains a reference to some "foreign" object or some other value (e.g., a hash), it won't be possible to call that method. :(

Ugh... Sorry for such a long rant! I hope, you have managed to read to here. :)

I'll be very happy to get to know what do you thing and what would you suggest to do. Feel free to share any your ideas on this topic, any fresh ideas will be very appreciated!

V.Melnik

In reply to Names of attribute accessors (Moose) by v_melnik

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.