Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Python OO v Moose

by tobyink (Canon)
on Feb 06, 2013 at 13:19 UTC ( [id://1017421]=note: print w/replies, xml ) Need Help??


in reply to Python OO v Moose

"there's a Python feature specific to OO that they really wish was in Moose"

I'd say the Moose OO model is far more powerful and useful than Python's. Roles, method modifiers, lazy builders, delegation and coercion are all really good for reducing repetitive code and improving OO design. With enough work most of that can be emulated in Python, but Moose gives it to you straight out of the box.

By the way; don't know if you're aware, but you can do this in Moose:

has [qw(arg1 arg2)] => (is => "rw");

Or of course:

has $_ => (is => "rw") for qw(arg1 arg2);

Also I'll offer a MooX::Struct example for your class. MooX::Struct is a compact builder for simple classes that mainly consist of attributes (not methods). It uses Moo which offers an easy upgrade path to Moose.

use v5.12; use MooX::Struct OurClass => [ qw( $arg1 $arg2 ), TO_STRING => sub { join "\n", @{+shift} }, ]; my $object = OurClass["Hello", "World"]; say $object;
package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Replies are listed 'Best First'.
Re^2: Python OO v Moose
by Ea (Chaplain) on Feb 07, 2013 at 16:01 UTC
    That's a little more compact than I was hoping for to show to non-Perl people, but I may start using it myself. <quote>Also I'll offer a MooX::Struct example for your class. MooX::Struct is a compact builder for simple classes that mainly consist of attributes (not methods).</quote> I was looking for this just last week, but I wanted one of the attributes to be a unique list, so there was a bit of overhead in writing the accessors.
    has 'name' => ( is => 'rw', isa => 'Str', required => 1 ); has 'members' => ( is => 'rw', isa => 'HashRef', default => sub{ {} }, ); sub add_members { my ($self, @members) = @_; $self->members()->{$_}++ for (@members); # no duplicates in list } sub list_members { my $self = shift; return keys %{$self->members()}; }
    I use it to create a group with a name and then add members to the list as I pick them out of a database. When I'm finished in the database, I go through all the groups and dump the members list. How would you do that in MooX::Struct and would it be able to modify the members list after instantiation?

    Sometimes I can think of 6 impossible LDAP attributes before breakfast.

      By default, all attributes in MooX::Struct are read-only, but it's easy to make them read-write...

      use MooX::Struct -rw, Person => [qw( $name @addresses )];

      For your members example, Moose's native traits would probably be helpful. Moo doesn't currently offer anything similar to this, but there is somebody developing such a beast - I believe it will be on CPAN soonish. I'd probably do something along these lines...

      use v5.14; package Person { use Moose; use overload q[""] => sub { $_[0]->name }, fallback => 1; has name => ( is => 'ro', isa => 'Str', required => 1, ); } package Club { use Moose; use overload q[""] => sub { $_[0]->name }, fallback => 1; has name => ( is => 'ro', isa => 'Str', required => 1, ); # This is a private attribute. We want people to only # manipulate the member list via add_members, etc. has _members => ( traits => ['Array'], is => 'ro', isa => 'ArrayRef[Person]', init_arg => undef, default => sub { [] }, handles => { add_members => 'push', has_members => 'count', list_members => 'elements', _uniq_members => 'uniq', }, ); # ensure uniqueness after add_members => sub { my $self = shift; @{ $self->_members } = $self->_uniq_members; }; } my $club = Club->new(name => "The Breakfast Club"); $club->add_members( Person->new(name => "Allison"), Person->new(name => "Andy"), Person->new(name => "Brian"), Person->new(name => "Brian"), # duplicate ); $club->add_members( Person->new(name => "Andy"), # duplicate Person->new(name => "Claire"), Person->new(name => "John"), ); say for $club->list_members;
      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1017421]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-04-24 01:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found