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


in reply to How to do this?

To unlock considerably more power in object-oriented applications, as well as dissolving some of the lumps in Perl's syntactic sugar, you may want to check out the very popular Moose (available on CPAN).

With Moose, your example can be written succinctly as follows:

#!/usr/bin/env perl use 5.010; package Father; use Moose; sub char { lc ref shift } package Son; use Moose; extends 'Father'; package main; say ref($_) . '->char() = ' . $_->char for new Father, new Son;

Output:

Father->char() = father Son->char() = son

You'll notice that I didn't have to explicitly create any constructors, nor did I have to monkey with any of the unintuitive bless machinations normally required to instantiate objects and work with subclasses.

I would probably take this a step further with a couple more features of Moose to turn the char() method into a proper class attribute:

has 'char' => ( is => 'ro', builder => '_build_char', # May override _build_char in subclasse +s init_arg => undef, # Disallow setting via constructor ); sub _build_char { lc ref shift }

On the surface, this doesn't change much: the output is the same, and thanks to init arg => undef and is => 'ro', its value is immutable just like the original char() method. However, rather than fetch and convert its reference type to lowercase every time it's called, the builder sub only fetches the result once, when the object is instantiated. For this example, the savings are small, but for more computationally expensive things, it will be significant. Perhaps more importantly, do not underestimate the expressive power of the has syntax; this makes it very clear what char does and what its limitations are.

I'm by no means a Moose evangelist (Moosevangelist?), but for someone learning Perl OO for the first time, I see no particularly compelling reason to learn the hard way. Over time, sure, you will pick up the knowledge of what's going on under the hood, but most of the time, you just don't need to bother.

If you're willing to put up with a many more module dependencies (around 50!), MooseX::Declare gives you even more syntactic sugar. The class definitions become:

use MooseX::Declare; class Father { has char => ( is => 'ro', builder => '_build_char', init_arg => undef, ); sub _build_char { lc ref shift } } class Son extends Father { }

How far you go should depend on the complexity of your object taxonomy.