Bubblegum
view release on metacpan or search on metacpan
lib/Bubblegum/Prototype.pm view on Meta::CPAN
my $baby = extend $papa,
name => 'baby bear',
type => 'tiny little baby bear',
responds => sub { "Who's eaten up all my porridge?" },
;
my $mama = extend $bear,
name => 'mama bear',
type => 'middle-sized mama bear',
attitude => 'confused',
responds => sub { "Who's been eating my porridge?" },
;
if ($papa && $mama && $baby && $baby->begets($papa)) {
my $statement = 'The %s said, "%s"';
$papa->name->titlecase->format($statement, $papa->responds)->say;
$mama->name->titlecase->format($statement, $mama->responds)->say;
$baby->name->titlecase->format($statement, $baby->responds)->say;
# The Papa Bear said, "Who's been eating my porridge?"
# The Mama Bear said, "Who's been eating my porridge?"
# The Baby Bear said, "Who's eaten up all my porridge?"
}
=head1 DESCRIPTION
Bubblegum::Prototype implements a thin prototype-like layer on top of the
L<Bubblegum> development framework. This module allows you to develop using a
prototype-based style while leveraging the L<Moo> and/or L<Moose> object
systems, and the Bubblegum framework. Bubblegum::Prototype allows you to create,
mutate, and extend classes with very little code.
Prototype-based programming is a style of object-oriented programming in which
classes are not present, and behavior reuse (known as inheritance in class-based
languages) is performed via a process of cloning existing objects that serve as
prototypes. 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 or JScript). B<Note: This
is an early release available for testing and feedback and as such is subject to
change.>
=head2 OVERVIEW
my $movie = object;
The object function, exported by Bubblegum::Prototype, creates an anonymous
class object (blessed hashref), derived from L<Bubblegum::Prototype::Instance>.
The function can optionally take a list of key/value pairs. The keys with values
which are code references will be implemented as class methods, otherwise
will be implemented as class attributes.
my $shrek = object
name => 'Shrek',
filepath => '/path/to/shrek',
lastseen => sub { (stat(shift->filepath))[8] },
directors => ['Andrew Adamson', 'Vicky Jenson'],
actors => ['Mike Myers', 'Eddie Murphy', 'Cameron Diaz'],
;
As previously stated, with prototype-based programming, reuse is commonly
achieved by extending prototypes (i.e. cloning existing objects which also serve
as templates). The extend function, also exported by Bubblegum::Prototype,
creates an anonymous class object (blessed hashref), derived from the specified
class or object.
my $shrek2 = extend $shrek,
name => 'Shrek2',
filepath => '/path/to/shrek2',
;
# additional credited director
$shrek2->directors->push('Conrad Vernon');
The thing being extended does not have to be an existing prototype, you can
actually extend any class or blessed object you like (provided that the
underlying structure is a hashref). You don't even have to preload the module,
simply pass the class name to the extend function, along with any parameters you
would like the class to be instantiated with. Please note that what is returned
is not an instance of the class specified, instead, what will be returned is a
prototype derived from the class specified.
my $imdb_search = extend 'IMDB::Film' => (
crit => $shrek2->name,
);
$shrek2 = extend $shrek2 => (
imdb_search => $imdb_search,
);
Any objects created via prototype can be further extended using the mixin_class
and/or mixin_role methods, provided by L<Bubblegum::Prototype::Instance>, which
uses the API of the underlying object system to extend the subject. Every
prototype object, which is an instance of L<Bubblegum::Prototype::Instance>, has
two default methods, proto, and prototype, both of which return a
L<Bubblegum::Prototype::Package> instance, which is used to manipulate the
associated prototype instance.
The mixin method, using the class key, upgrades the subject using multiple
inheritance. Please note that calling this method more than once will replace
your superclasses, not add to them.
# replaces existing superclass with testing superclass
$film_search->proto->mixin(class => 'testing');
The mixin method, using the role key, modifies the subject using role
composition. Please note that applying a role will not overwrite existing
methods. If you desire to overwrite existing methods, please extend the object,
then apply the roles desired.
# add credentials and request methods dynamically
$film_search->proto->mixin(role => 'authorization');
$film_search->proto->mixin(role => 'advanced_search');
One of the very cool and interesting practices that this style of programming
encourages is modifying class definitions at runtime. This is achieved using
( run in 2.165 seconds using v1.01-cache-2.11-cpan-ceb78f64989 )