NAME
MooseX::Prototype - prototype-based programming for Moose
SYNOPSIS
From Wikipedia: *"Prototype-based programming is a style of
object-oriented programming in which classes are not present, and
behaviour reuse (known as inheritance in class-based languages) is
performed via a process of cloning existing objects that serve as
prototypes."*
use MooseX::Prototype;
my $Person = object {
name => undef,
};
my $Employee = $Person->new->extend({
job => undef,
employer => undef,
});
my $CivilServant = $Employee->new(
employer => 'Government',
);
$CivilServant->extend({
department => undef,
});
my $bob = $CivilServant->new(
name => 'Robert',
department => 'HMRC',
job => 'Tax Inspector',
);
print $bob->dump;
# $VAR1 = bless( {
# name => 'Robert',
# job => 'Tax Inspector',
# department => 'HMRC',
# employer => 'Government'
# }, 'MooseX::Prototype::__ANON__::0006' );
DESCRIPTION
Due to familiarity with class-based languages such as Java, many
programmers assume that object-oriented programming is synonymous with
class-based programming. However, class-based programming is just one kind
of object-oriented programming style, and other varieties exist such as
role-oriented, aspect-oriented and prototype-based programming.
A prominent example of a prototype-based programming language is
ECMAScript (a.k.a. Javascript/JScript/ActionScript). ECMAScript does
provide a thin class-like layer over the top of its prototype-based OO
system, which some (even experienced) ECMAScript developers rarely see
beyond.
This module implements a thin prototype-like layer on top of Moose's
class/role-based toolkit.
Ex-Nihilo Object Creation
In prototype-based languages, objects are created by cloning other
objects. But it's often useful to be able to magic up an object out of
nowhere. MooseX::Prototype provides a convenience function to do this:
`object \%attrs`
Creates a new object with the given attributes. The hash is treated as
attribute-name, attribute-value pairs, but any names beginning with
"&" are installed as methods. For example:
my $person = object {
"name" => "Robert",
"&changeName" => sub {
my ($self, $newname) = @_;
$self->name($newname);
},
};
Objects created this way inherit from Moose::Object and perform the
`MooseX::Prototype::Trait::Object` role.
Creating Objects from a Prototype
A prototype is just an object. When you create a new object from it, the
prototype will be cloned and the new object will inherit all its
attributes and methods.
`$prototype->new(%attrs)`
Creates a new object which inherits its methods and attributes from
$prototype. The %attrs hash can override attribute values from the
prototype, but cannot add new attributes or methods.
This method is provided by the `MooseX::Prototype::Trait::Object`
role, so $prototype must perform that role.
`$prototype->create_class`
Rather than creating a new object from a prototype, this creates a
whole new Moose class which can be used to instantiate objects. If you
need to create a whole bunch of objects from a prototype, it is
probably more efficient to create a class and use that, rather than
just calling `new` a bunch of times.
The class can be given a name, a la:
$prototype->create_class("Foo::Bar");
Otherwise an arbitary name will be generated and returned.
This method is provided by the `MooseX::Prototype::Trait::Object`
role, so $prototype must perform that role.
`create_class_from_prototype($prototype)`
A convenience function allowing you to use arbitary Moose objects
(which lack the `create_class` method) as prototypes.
Also note:
my $obj = create_class_from_prototype($proto)->new(%attrs);
This function is not exported by default, but can be exported using:
use MooseX::Prototype -all;
Extending Existing Objects
A key feature of Javascript is that new attributes and methods can be
given to an object using simple assignment;
my_object.some_attribute = 123;
my_object.some_method = function () { return 456 };
In MooseX::Prototype, there is an explicit syntax for adding new
attributes and methods to an object.
`$object->extend(\%attrs)`
As per ex-nihilo object creation, the attribute hashref can define
attribute name-value pairs, or new methods with a leading "&".
HISTORY
Version 0.001 of MooseX::Prototype consisted of just a single function,
`use_as_prototype` which was much the same as
`create_class_from_prototype`.
Version 0.002 is an almost complete rewrite.
BUGS
Please report any bugs to
<http://rt.cpan.org/Dist/Display.html?Queue=MooseX-Prototype>.
SEE ALSO
Object::Prototype, Class::Prototyped, JE::Object.
AUTHOR
Toby Inkster <tobyink@cpan.org>.
COPYRIGHT AND LICENCE
This software is copyright (c) 2012 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the
same terms as the Perl 5 programming language system itself.
DISCLAIMER OF WARRANTIES
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.