NAME

Class::LOP - The Lightweight Object Protocol

DESCRIPTION

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.

SYNOPSIS

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.

METHODS

init

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');

new

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.

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.

warnings_strict

Enables use warnings and use strict pragmas in Class::LOP modules

$class->warnings_strict();

getscope

Basically just a caller. Use this in your modules to return the class name

my $caller = $class->getscope();

class_exists

Checks to make sure the class has been imported

use Some::Module;

if ($class->class_exists()) {
    print "It's there!\n";
}

method_exists

Detects if a specific method in a class exists

if ($class->method_exists($method_name)) { .. }

subclasses

Returns an list of subclassed modules

my @subclass_mods = $class->subclasses();
for (@subclass_mods) {
    print "$_\n";
}

superclasses

Returns a list of superclass (base) modules

my @superclass_mods = $class->superclasses();
for (@superclass_mods) {
    print "$_\n";
}

import_methods

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.

extend_class

Pretty much the same as use base 'Mother::Class'. The first parameter is the subclass, and the following array will be its "mothers".

my @mommys = qw(This::Class That::Class);
$class->extend_class(@mommys)

have_accessors

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.

create_constructor

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;

create_method

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();

add_hook

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.

list_methods

Returns a list of all the methods within an initialised class. It will filter out classes

my @methods = Class::LOP->init('SomeClass')->list_methods();

clone_object

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.

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.

override_method

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

AUTHOR

Brad Haywood <brad@perlpowered.com>

LICENSE

This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.