Bubblegum

 view release on metacpan or  search on metacpan

lib/Bubblegum/Prototype.pm  view on Meta::CPAN

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
standard modern Perl object system operations. For example:

    $shrek2->proto->make(quote => sub {
        'Better out than in I always say'
    });

    my $shrek3 = extend $shrek2;
    $shrek3->proto->around(quote => sub {
        my ($orig, $self, $comment) = @_;
        $comment->say and $self->$orig(@args)->say;
    });

    $shrek3->quote('Oh! Excuse me');

=head1 AUTHOR

Al Newkirk <anewkirk@ana.io>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2013 by Al Newkirk.

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

=cut



( run in 4.584 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )