Programming with Moose/Problems solved/Accessors

Perl has two complex (non-Scalar) data types: Hashes and Arrays; ie., Associative Arrays, and the regular plain-Jane ones. One of the two might be better for one task, and not applicable for another; but that doesn't matter, with Moose your program isn't as tied to a perl data structure anyway. Moreover, neither of these data types are objects. Think archaic rather than modern. You can't have an event trigger when you write a new key-value pair to a hash, or for that matter when you push a new element onto an array. Why can't you, because by the traditional definition of an array it is only a contiguous block of memory. Perl fixed that for good reason, but it stopped there.[1]

The old wayEdit

Traditionally, Class::Accessor, has done the most for arena, we'll see that soon. The problem it solved was a big and simple one, and it didn't overachieve one bit: if you've got a hash and you don't want a key: foobar to be inserted, how do you go about it? You simply bless the hash into an object and say what accessors should be generated. Now this "hash" acts as watered down model that your module can wrap to achieve the goals of the program. When an unrelated function is called perl realizes it can't resolve the method to a matching sub and errors.[2]

An ExampleEdit

Examine the terseness of this code.

package OldWay;
use strict;
use warnings;
 
use base 'Class::Accessor'; ## or C::A::Fast, or C::A::More, et al.
 
BEGIN { Class::Accessor->mk_accessors( qw/ foo bar baz / ) }
 
sub new {
	my $class = shift;
	bless {}, $class;
}
 
package main;
use strict;
use warnings;
 
my $obj = OldWay->new;
 
## These work
$obj->foo( 1 );
$obj->bar( OldWay->new );
$obj->baz( 'foo' );
 
## Anything else will die
$obj->quz( 1 ); #die

Here we create an object, essentially a hash that permits only three keys. The getters and setters for this hash directly correlate to the keys in the underlying perl hash. Remember, that a Perl object is very simple. complexities are left as an exercise to the programmer.

Invoking the MooseEdit

Truth be told, Moose is more than a replacement for Class::Accessor. So, off the shelf, it won't compete with the simplicity of Class::Accessor. In this section however, we will see Moose's analog.[3]

An ExampleEdit

package NewWay;
use Moose;
 
has 'foo' => ( isa  => 'Value', is => 'rw' );
has 'bar' => ( isa  => 'Value', is => 'rw' );
has 'baz' => ( isa  => 'Value', is => 'rw' );
# or just
# has [qw/ foo bar baz /] => ( isa  => 'Value', is => 'rw' );
 
package main;
use strict;
use warnings;
 
my $obj = NewWay->new;
 
## Rest of the module is the same..
 
## These work
$obj->foo( 1 );
$obj->bar( NewWay->new );
$obj->baz( 'foo' );
 
## Anything else will die
$obj->quz( 1 ); #die

Pretty simple. No syntax thus far really needs explaining -- but in the next section we will anyway.

New SyntaxEdit

For clarity and those who just can't learn by example:

hasEdit

Further information: Programming with Moose/Syntax/has

has is one of few Moose keywords, it begins a Moose expression that declares a statement.

isaEdit

See also: has

isa in the context of has refers to the TypeConstraint of the object. Moose has a built in type system, and this keyword, which will be explained further in the next chapter specifies what values this attribute is to accept.

isEdit

See also: has

is in the context of has refers to the type of accessors to be created. A value of rw will instruct Moose to forge a setter and getter, while a value of ro will only yield a get'er.

FootnotesEdit

  1. ^ Unless of course you have explicitly crafted a sub AUTOLOAD {}, let's not be bothered with this exception though.
  2. ^ By fixed we mean you can push onto both sides of the array. There is no guarantee new data will be contiguous to the old data. When you program with perl you aren't supposed to think at a low level, don't worry about what happens just know it'll work.
  3. ^ Of course, with Moose::Tiny you will probably get a more powerful and more terse alternative to Class::Accessor but we will address MooseX:: and alternatives at a later point in this book.
Last modified on 16 October 2011, at 23:59