NAME

Coat -- A light and self-dependent meta-class for Perl5

DESCRIPTION

This module was inspired by the excellent Moose meta class which provides enhanced object creation for Perl5.

Moose is great, but has huge dependencies which makes it difficult to use in restricted environments.

This module implements the basic goodness of Moose, namely accessors automagic, hook modifiers and inheritance facilities.

It is not Moose but the small bunch of features provided are Moose-compatible. That means you can start with Coat and, if later you get to the point where you can or want to upgrade to Moose, your code won't have to change : every features provided by Coat exist in the Moose's API (but the opposite is not true, as you can imagine).

SYNTAX

When you define a class with Coat (eg: use Coat;), you declare a class that inherits from the main Coat mother-class: Coat::Object. Coat is the meta-class, Coat::Object is the mother-class.

The meta-class will help you define the class itself (inheritance, attributes, method modifiers) and the mother-class will provide to your class a set of default instance-methods such as a constructor and default accessors for your attributes.

Here is a basic example with a class "Point":

package Point;
use Coat;  # once the use is done, the class already 
           # inherits from Coat::Object, the mother-class.

# describe attributes...
has 'x' => (isa => 'Int', default => 0);
has 'y' => (isa => 'Int', default => 0);

# and your done
1;

my $point = new Point x => 2, y => 4;
$point->x;    # returns 2
$point->y;    # returns 4
$point->x(9); # returns 9

Note that there's no need to import the "strict" and "warnings" modules, it's already exported by Coat when you use it.

METHODS

Coat provides you with static methods you use to define your class. They're respectingly dedicated to set inheritance, declare attributes and define method modifiers (hooks).

INHERITANCE

The keyword "extends" allows you to declare that a class "Child" inherits from a class "Parent". All attributes properties of class "Parent" will be applied to class "Child" as well as the accessors of class "Parent".

Here is an example with Point3D, an extension of Point previously declared in this documentation:

package Point3D;

use Coat;
extends 'Point';

has 'z' => (isa => 'Int', default => 0):

my $point3d = new Point3D x => 1, y => 3, z => 1;
$point3d->x;    # will return: 1
$point3d->y;    # will return: 3
$point3d->z;    # will return: 1

ATTRIBUTES AND ACCESSORS

The static method has allows you to define attributes for your class.

You can handle each attribute options with the %options hashtable. The following options are supported:

isa

When declaring an attribute, it is possible to restrict allowed values to those that validate a type.

See Coat::Types for supported types.

default

The attribute's default value (the attribute will have this value at instanciation time if none given).

Be aware that like with Moose, only plain scalars and code references are allowed when declaring a default value (wrap other references in subs).

METHOD MODIFIERS (HOOKS)

Like Moose, Coat lets you define hooks. There are three kind of hooks : before, after and around.

before

When writing a "before" hook you can catch the call to an inherited method, and execute some code before the inherited method is called.

Example:

package Foo;
use Coat;

sub method { return 4; }

package Bar;
use Coat;
extends 'Foo';

around 'method' => sub {
  my ($self, @args) = @_;
  # ... here some stuff to do before Foo::method is called
};

after

When writing an "after" hook you can catch the call to an inherited method and execute some code after the original method is executed. You receive in your hook the result of the mother's method.

Example:

package Foo;
use Coat;

sub method { return 4; }

package Bar;
use Coat;
extends 'Foo';

my $flag;

after 'method' => sub {
  my ($self, @args) = @_;
  $flag = 1;
};

around

When writing an "around" hook you can catch the call to an inherited method and actually redefine it on-the-fly.

You get the code reference to the parent's method and its arguments, and can do what you want then. It's a very powerful hook but also dangerous, so be careful when writing such a hook not to break the original call.

Example:

package Foo;
use Coat;

sub method { return 4; }

package Bar;
use Coat;
extends 'Foo';

around 'method' => sub {
  my $orig = shift;
  my ($self, @args) = @_;

  my $res = $self->$orig(@args);
  return $res + 3;
}

SEE ALSO

Moose is the mother of Coat, every concept inside Coat was friendly stolen from it, you definitely want to look at Moose.

AUTHORS

This module was written by Alexis Sukrieh <sukria+perl@sukria.net>

Strong and helpful reviews were made by Stevan Little and Matt (mst) Trout ; this module wouldn't be there without their help. Huge thank to them.

COPYRIGHT AND LICENSE

Copyright 2007 by Alexis Sukrieh.

http://www.sukria.net/perl/coat/

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.