Class::LOP - The Lightweight Object Protocol
Just like Moose is built from Class::MOP. You can build your own using this module. It is a little different from Class::MOP though, because it doesn't use a meta class, it has less features, but it's a lot faster. If you need a lightweight object protocol, this may be the tool for you. Using this module you could build an extremely quick OOP framework that could be used from a CLI or as a standard module.
package Goosey; use Class::LOP; sub import { my $caller = caller(); # Methods can be chained for simplicity and easy tracking. # Below, we'll create the 'new' constructor, enable warnings and strict, and also # bestow the accessors feature, so our module can create them Class::LOP->init($caller) ->create_constructor ->warnings_strict ->have_accessors('has'); # import multiple methods into the specified class Class::LOP->init('Goosey')->import_methods($caller, qw/ extends after before /); } # Add a few hook modifiers # This code sure looks a lot cleaner than writing it yourself ;-) sub after { my ($name, $code) = @_; Class::LOP->init(caller())->add_hook( type => 'after', name => $name, method => $code, ); } # Extending a class is similar to 'use base' # You may have also seen this from Moose # ->extend_class() makes it really easy for you sub extends { my (@classes) = @_; Class::LOP->init(caller()) ->extend_class(@classes); } # MyClass.pm package MyClass; use Goosey; # enables warnings/strict extends 'Some::Module::To::Subclass'; has 'name' => ( is => 'rw', default => 'Foo' ); after 'name' => sub { print "This code block runs after the original!\n"; };
Wow, that all looks familiar.. but we wrote it all in a fairly small amount of code. Class::LOP takes care of the dirty work for you, so you can just worry about getting the features in your module that you want.
Initialises a class. This won't create a new one, but will set the current class as the one specified, if it exists. You can then chain other methods onto this, or save it into a variable for repeated use.
Class::LOP->init('SomeClass');
Initialises a class, but will also create a new one should it not exist. If you're wanting to initialise a class you know exists, you're probably better off using init, as it involves less work.
init
Class::LOP->new('MyNewClass') ->create_method('foo', sub { print "foo!\n" }); my $class = MyNewClass->new(); $class->foo(); # prints foo!
Using new then chaining create_method onto it, we were able to create a class and a method on-the-fly.
new
create_method
Enables use warnings and use strict pragmas in Class::LOP modules
use warnings
use strict
$class->warnings_strict();
Basically just a caller. Use this in your modules to return the class name
caller
my $caller = $class->getscope();
Checks to make sure the class has been imported
use Some::Module; if ($class->class_exists()) { print "It's there!\n"; }
Detects if a specific method in a class exists
if ($class->method_exists($method_name)) { .. }
Returns an list of subclassed modules
my @subclass_mods = $class->subclasses(); for (@subclass_mods) { print "$_\n"; }
Returns a list of superclass (base) modules
my @superclass_mods = $class->superclasses(); for (@superclass_mods) { print "$_\n"; }
Injects existing methods from the scoped module to a specified class
$class->import_methods($destination_class, qw/this that and this/);
Optionally, import_methods can return errors if certain methods don't exist. You can read these errors with last_errors. This is only experimental at the moment.
import_methods
last_errors
Pretty much the same as use base 'Mother::Class'. The first parameter is the subclass, and the following array will be its "mothers".
use base 'Mother::Class'
my @mommys = qw(This::Class That::Class); $class->extend_class(@mommys)
Adds Moose-style accessors to a class. First parameter is the class, second will be the name of the method to create accessors.
# Goosey.pm $class->have_accessors('acc'); # test.pl use Goosey; acc 'x' => ( is => 'rw', default => 7 );
Currently the only two options is default and is.
default
is
Simply adds the new method to your class. I'm wondering whether this should be done automatically? The aim of this module is to give the author as much freedom as possible, so I chose not to.
$class->create_constructor;
Adds a new method to an existing class.
$class->create_method('greet', sub { my $self = shift; print "Hello, World from " . ref($self) . "\n"; }); MooClass->greet();
Adds hook modifiers to your class. It won't import them all - only use what you need :-)
$class->add_hook( type => 'after', method => $name, code => $code, );
The types are after, before, and around.
after
before
around
Returns a list of all the methods within an initialised class. It will filter out classes
my @methods = Class::LOP->init('SomeClass')->list_methods();
Takes an object and spits out a clone of it. This means mangling the original will have no side-effects to the cloned one I know DateTime has its own clone method, but still, it's a good example.
clone
my $dt = DateTime->now; my $dt2 = Class::LOP->init($dt)->clone_object; print $dt->add(days => 5)->dmy() . "\n"; print $dt2->dmy() . "\n";
Simply changing $dt2 = $dt would mean both results would have the same date when we printed them, but because we cloned the object, they are separate.
$dt2 = $dt
Unlike create_method, this method will let you replace the existing one, thereby overriding it.
sub greet { print "Hello\n"; } Class::LOP->init('ClassName')->override_method('greet', sub { print "Sup\n" }); greet(); # prints Sup
Brad Haywood <brad@perlpowered.com>
This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.
To install Sub::Mage, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Sub::Mage
CPAN shell
perl -MCPAN -e shell install Sub::Mage
For more information on module installation, please visit the detailed CPAN module installation guide.