Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I would suggest that the answer to #3 is:

Whether or not you've outgrown Class::Struct, in 2013 there is very little reason to use it. If you choose to use an OO helper (rather than writing OO by hand), and you want to stay light-weight and fast, use Moo. It's true that it is not core. But it is fast, minimal, and actively developed and used. And it's largely compatible with Moose classes.

With Moo, your example code above would look like this:

package Cat; use Moo; use MooX::Types::MooseLike::Base qw(:all); has name => ( is => 'ro', isa => Str ); 1; package Litter; use Moo; use MooX::Types::MooseLike::Base qw(:all); has cats => ( is => 'ro', isa => ArrayRef ); 1; package main; my $cat1 = Cat->new(name=>'Garfield'); my $cat2 = Cat->new(name=>'Felix'); my $litter = Litter->new(cats => [$cat1, $cat2]); for (@{$litter->cats}) { print $_->name . "\n" }

...but in this example Moo is doing more: It's assuring that the accessors "name" and "cats" can't be modified after the object has been instantiated. It's also assuring that "name" is a string.

But one real advantage is that instead of isa => ArrayRef, you could say:

isa => sub { my $param = shift; die "<<$param>> must be an array ref" unless ref $param eq 'ARRAY'; foreach my $element ( @{$param} ) { die "<<$element>> isn't a Cat object" unless ref $element eq 'Cat'; } }

Now your object instantiation verifies that all of the elements passed by Litter->new( cats => [ ... ] ) are Cats objects. You could even get more "general" by skipping the "ref $element eq 'Cat'" test, and instead allowing any sufficiently Cat-like object to pass:

die "<<$element>> must have a name attribute" unless $element->can('name');

With Moo you could also define a BUILDARGS subroutine that silently drops any elements from cats => [...] that don't have a "name" attribute.... if you want that behavior instead.

Now, going back to the MooX::Types::MooseLike::Base example, even these constructs are possible:

isa => ArrayRef[ InstanceOf['Cat'] ]

And if you want your Litter class to accept any object that has a name attribute (in other words, a litter of bobcats would be fine too, as long as they have a name attribute), you can...

isa => ArrayRef[ HasMethods['name'] ]

Which provides clear semantics and avoids complexity. Moo makes this sort of thing pretty simple. Moose, being Moo's big uncle also has similar syntactic sugar. But Moo is so light-weight it's a great fit for small projects.

Update: So putting it all together, here's your original code with the Moo and MooX::Types::MooseLike::Base syntax:

package Cat; use Moo; use MooX::Types::MooseLike::Base 'Str'; has name => ( is => 'ro', isa => Str ); 1; package Litter; use Moo; use MooX::Types::MooseLike::Base qw( ArrayRef HasMethods ); has cats => ( is => 'ro', isa => ArrayRef [ HasMethods ['name'] ] ); 1; package main; my @cat_names = qw( Garfield Felix ); my $litter = Litter->new( cats => [ map { Cat->new( name => $_ ) } @cat_names ] ); print $_->name . "\n" for @{ $litter->cats };

Updated: Removed quotes from isa => checks since Moo requires a subref, and since that's what MooX::Types::MooseLike::Base provides.


In reply to Re: Perl OO with Class::Struct by davido
in thread Perl OO with Class::Struct by VinsWorldcom

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, 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, 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.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others cooling their heels in the Monastery: (2)
    As of 2018-05-23 00:01 GMT
    Find Nodes?
      Voting Booth?