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 mother-class: Coat::Object.The Coat module itself exports all the symbols needed to build a class and Coat::Meta provides access to the meta class informations (attribute descriptions, inheritance data, etc).
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; it should be used like the following:has $name => %options
This will install an attribute of a given $name into the current class. The following options are supported:
- is => 'rw'|'ro'
- The is option accepts either rw (for read/write) or ro (for read only). These will create either a read/write accessor or a read-only accessor respectively, using the same name as the $name of the attribute.
- isa => $type_name
- The isa option uses Coat's type constraint facilities to set up runtime type checking for this attribute. Coat will perform the checks during class construction, and within any accessors. The $type_name argument must be a string. The string may be either a class name or a type defined by Coat::Types.
- required => (1|0)
- This marks the attribute as being required. This means a defined value must be supplied during class construction, and the attribute may never be set to "undef" with an accessor.
- default
- Change the default value of an attribute. Be aware that like with Moose, only plain scalars and code references are allowed when declaring a default value (wrap other references in subs).
- trigger => $code
- The trigger option is a CODE reference which will be called after the value of the attribute is set. The CODE ref will be passed the instance itself, the updated value and the attribute meta-object (this is for more advanced fiddling and can typically be ignored). You cannot have a trigger on a read-only attribute.
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'; before '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; }
AUTHORS
This module was written by Alexis Sukrieh <[email protected]>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.