CatalystX::CRUD::Object - an instance returned from a CatalystX::CRUD::Model


CatalystX-CRUD documentation Contained in the CatalystX-CRUD distribution.

Index


Code Index:

NAME

Top

CatalystX::CRUD::Object - an instance returned from a CatalystX::CRUD::Model

SYNOPSIS

Top

 package My::Object;
 use base qw( CatalystX::CRUD::Object );

 sub create { shift->delegate->save }
 sub read   { shift->delegate->load }
 sub update { shift->delegate->save }
 sub delete { shift->delegate->remove }

 1;

DESCRIPTION

Top

A CatalystX::CRUD::Model returns instances of CatalystX::CRUD::Object.

The assumption is that the Object knows how to manipulate the data it represents, typically by holding an instance of an ORM or other data model in the delegate accessor, and calling methods on that instance.

So, for example, a CatalystX::CRUD::Object::RDBO has a Rose::DB::Object instance, and calls its RDBO object's methods.

The idea is to provide a common CRUD API for various backend storage systems.

METHODS

Top

The following methods are provided.

new

Generic constructor. args may be a hash or hashref.

delegate

The delegate() accessor is a holder for the object instance that the CXCO instance has. A CXCO object "hasa" instance of another class in its delegate() slot. The delegate is the thing that does the actual work; the CXCO object just provides a container for the delegate to inhabit.

Think of delegate as a noun, not a verb, as in "The United Nations delegate often slept here."

REQUIRED METHODS

Top

A CXCO subclass needs to implement at least the following methods:

create

Write a new object to store.

read

Load a new object from store.

update

Write an existing object to store.

delete

Remove an existing object from store.

AUTOLOAD

Some black magic hackery to make Object classes act like they are overloaded delegate()s.

can( method )

Overrides basic can() method to call can() first on the delegate and secondly (fallback) on the Object class itself.

AUTHOR

Top

Peter Karman, <perl at peknet.com>

BUGS

Top

Please report any bugs or feature requests to bug-catalystx-crud at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CatalystX-CRUD. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc CatalystX::CRUD

You can also look for information at:

* AnnoCPAN: Annotated CPAN documentation

http://annocpan.org/dist/CatalystX-CRUD

* CPAN Ratings

http://cpanratings.perl.org/d/CatalystX-CRUD

* RT: CPAN's request tracker

http://rt.cpan.org/NoAuth/Bugs.html?Dist=CatalystX-CRUD

* Search CPAN

http://search.cpan.org/dist/CatalystX-CRUD

ACKNOWLEDGEMENTS

Top

COPYRIGHT & LICENSE

Top


CatalystX-CRUD documentation Contained in the CatalystX-CRUD distribution.
package CatalystX::CRUD::Object;
use strict;
use warnings;
use Moose;
with 'MooseX::Emulate::Class::Accessor::Fast';
with 'Catalyst::ClassData';
use base qw( CatalystX::CRUD );
use Carp;
use MRO::Compat;
use mro 'c3';

__PACKAGE__->mk_ro_accessors(qw( delegate ));
__PACKAGE__->mk_classdata('delegate_class');

our $VERSION = '0.51';

sub new {
    my $class = shift;
    my $arg = ref( $_[0] ) eq 'HASH' ? $_[0] : {@_};
    return $class->next::method($arg);
}

sub create { shift->throw_error("must implement create") }
sub read   { shift->throw_error("must implement read") }
sub update { shift->throw_error("must implement update") }
sub delete { shift->throw_error("must implement delete") }

sub AUTOLOAD {
    my $obj            = shift;
    my $obj_class      = ref($obj) || $obj;
    my $delegate_class = ref( $obj->delegate ) || $obj->delegate;
    my $method         = our $AUTOLOAD;
    $method =~ s/.*://;
    return if $method eq 'DESTROY';
    if ( $obj->delegate->can($method) ) {
        return $obj->delegate->$method(@_);
    }

    $obj->throw_error( "method '$method' not implemented in class "
            . "'$obj_class' or '$delegate_class'" );

}

# this overrides the basic can()
# to always call secondary can() on its delegate.
# we have to UNIVERSAL::can because we are overriding can()
# and would otherwise have a recursive nightmare.

sub can {
    my ( $obj, $method, @arg ) = @_;
    if ( ref($obj) ) {

        # object method tries object_class first,
        # then the delegate().
        my $subref = UNIVERSAL::can( ref($obj), $method );
        return $subref if $subref;
        if ( defined $obj->delegate ) {
            return $obj->delegate->can( $method, @arg );
        }
        return undef;
    }
    else {

        # class method
        return UNIVERSAL::can( $obj, $method );
    }
}

1;
__END__