The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Object::Simple - Light Weight Minimal Object System

VERSION

Version 2.0015

FEATURES

1. You can define accessors in very simple way.
2. new method is prepared.
3. You can define variouse accessor option(default, type, chained, weak)
4. you can use Mixin system like Ruby

If you use Object::Simple, you are free from bitter work writing new and accessors repeatedly.

SYNOPSIS

    # Class definition( Book.pm )
    package Book;
    use Object::Simple;
    
    sub title  : Attr {}
    sub author : Attr {}
    sub price  : Attr {}
    
    Object::Simple->build_class; # End of module. Don't forget to call 'build_class' method
    
    # Using class
    use Book;
    my $book = Book->new(title => 'a', author => 'b', price => 1000);
    
    # Default value
    sub author : Attr { default => 'Kimoto' }
    
    #Automatically build
    sub author : Attr { auto_build => 1 }
    sub build_author{ 
        my $self = shift;
        $self->author( $self->title . "b" );
    }
    
    # Read only accessor
    sub year : Attr { read_only => 1 }
    
    # weak reference
    sub parent : Attr { weak => 1 }
    
    # method chaine
    sub title : Attr { chained => 1 }
    
    # variable type
    sub authors : Attr { type => 'array' }
    sub country : Attr { type => 'hash' }
    
    # convert to object
    sub url : Attr { convert => 'URI' }
    sub url : Attr { convert => sub{ ref $_[0] ? $_[0] : URI->new($_[0]) } }
    
    # derefference of returned value
    sub authors    : Attr { type => 'array', deref => 1 }
    sub country_id : Attr { type => 'hash',  deref => 1 }
    
    # trigger option
    sub error : Attr { trigger => sub{ $_[0]->state('error') } }
    sub state : Attr {}
    
    # translate option
    sub person : Attr { default => sub{ Person->new } }
    sub name   : Attr { translate => 'person->name' }
    sub age    : Attr { translate => 'person->age' }
    
    # Inheritance
    package Magazine;
    use Object::Simple( base => 'Book' );
    
    # Mixin
    package Book;
    use Object::Simple( 
        mixins => [ 
            'Object::Simple::Mixin::AttrNames',
            'Object::Simple::Mixin::AttrOptions'
        ]
    );
 

METHODS

new

new is prepared.

    use Book;
    my $book = Book->new( title => 'a', author => 'b', price => 1000 );
 

This new can be overided.

    # initialize object
    sub new {
        my $self = shift->SUPER::new(@_);
        
        # initialize object
        
        return $self;
    }
    
    # arrange arguments
    sub new {
        my ($self, @args) = @_;
        
        my $self = $self->SUPER::new(title => $_[0], author => $_[1]);
        
        return $self;
    }
 

build_class

resist attribute and create accessors.

Script must build_class 'Object::Simple->build_class;'

    Object::Simple->build_class; # End of Object::Simple!

ACCESSOR OPTIONS

default

You can define attribute default value.

    sub title : Attr {default => 'Good news'}
 

If you define default values using reference or Object, you need wrapping it by sub{}.

    sub authors : Attr { default => sub{['Ken', 'Taro']} }
 

auto_build

When accessor is called first,a methods is called to build attribute.

    sub author : Attr { auto_build => 1 }
    sub build_author{
        my $self = shift;
        $self->atuhor( Person->new );
    }
 

Builder method name is build_ATTRIBUTE_NAME by default;

You can specify build method .

    sub author : Attr { auto_build => 1 }
    sub create_author{
        my $self = shift;
        $self->atuhor( Person->new );
    }
 

read_only

You can create read only accessor

    sub title: Attr { read_only => 1 }
 

chained

You can chain method

    sub title  : Attr { chained => 1 }
    sub author : Attr { chained => 1 }
    
    $book->title('aaa')->author('bbb')->...
    

weak

attribute value is weak reference.

    sub parent : Attr {weak => 1}

type

You can specify variable type( array, hash );

    # variable type
    sub authors : Attr { type => 'array' }
    sub country_id : Attr { type => 'hash' }

If you specity 'array', arguments is automatically converted to array reference

     $book->authors('ken', 'taro'); # ('ken', 'taro') -> ['ken', 'taro']
     $book->authors('ken');         # ('ken')         -> ['ken']

If you specity 'hash', arguments is automatically converted to hash reference

     $book->country_id(Japan => 1); # (Japan => 1)    -> {Japan => 1}

convert

You can convert a non blessed scalar value to object.

    sub url : Attr { convert => 'URI' }
    
    $book->url('http://somehost'); # convert to URI->new('http://somehost')

You can also convert a scalar value using your convert function.

    sub url : Attr { convert => sub{ ref $_[0] ? $_[0] : URI->new($_[0]) } }

deref

You can derefference returned value.You must specify it with 'type' option.

    sub authors : Attr { type => 'array', deref => 1 }
    sub country_id : Attr { type => 'hash',  deref => 1 }

    my @authors = $book->authors;
    my %country_id = $book->country_id;
    

trigger

You can defined trigger function when value is set.

    sub error : Attr { trigger => sub{ $_[0]->stete('error') } }
    sub state : Attr {}

translate

You can create accessor shortcut of object of attribute value.

    sub person : Attr { default => sub{ Person->new } }
    sub name   : Attr { translate => 'person->name' }
    sub age    : Attr { translate => 'person->age' }

INHERITANCE

    # Inheritance
    package Magazine;
    use Object::Simple( base => 'Book' );
 

Object::Simple do not support multiple inheritance because it is so complex.

MIXIN

Object::Simple support mixin syntax

    # Mixin
    package Book;
    use Object::Simple( 
        mixins => [ 
            'Object::Simple::Mixin::AttrNames',
            'Object::Simple::Mixin::AttrOptions'
        ]
    );
 

Object::Simple mixin merge mixin class attribute.

    # mixin class
    package Some::Mixin;
    use Object::Simple;
    
    sub m2 : Attr {}
    
    Object::Simple->build_class;

    # using mixin class
    package Some::Class;
    use Object::Simple( mixins => [ 'Some::Mixin' ] );
    
    sub m1 : Attr {}
    
    Object::Simple->build_class;

Because Some::Mixin is mixined, Some::Class has two attribute m1 and m2.

METHODS SEARCHING ORDER

Method searching order is like Ruby.

If method names is crashed, method search order is the following

1. This class

2. Mixin class2

3. Mixin class1

4. Base class

     +--------------+
   4 | Base class   |
     +--------------+
           |
     +--------------+
   3 | Mixin class1 |
     +--------------+
           |
     +--------------+
   2 | Mixin class2 |
     +--------------+
           |
     +--------------+
   1 | This class   |
     +--------------+

    #       1
    package ThisClass;
    #                       4                       3              2
    Object::Simple(base => 'BaseClass', mixins => ['MixinClass1', 'MixinClass2']);

CALL MIXINS METHODS

You can call all methods of mixins methods.

    $self->Object::Simple::MIXINS::initialize; # call all initialize of mixin classes
    
    $self->Object::Simple::MIXINS::DESTROY;    # call all DESTROY of mixin classes

    $self->Object::Simple::MIXINS::method;     # any method ok!

For example, you can call all initialize methods of mixin classes package ThisClass; Object::Simple(mixins => ['MixinClass1', 'MixinClass2']);

    sub initialize {
        my $self = shift;
        
        # call initialize of all mixin class
        $self->Object::Simple::MIXINS::initialize;
    }

CALL UPPER CLASS METHODS

You can call upper methods.

    $self->Object::Simple::UPPER::method;

Method is searched by the following order and call the method.

1. Mixin class2

2. Mixin class1

3. Base class

    package ThisClass;
    Object::Simple(base => 'BaseClass', mixins => ['MixinClass1', 'MixinClass2']);

    sub run {
        my $self = shift;
        $self->Object::Simple::UPPER::run;
    }

If MixinClass1 have run methods, MixinClass1::run is called.

If MIxinClass1 and MixinClass2 have run method, MixinClass2::run is called.

using your MODIFY_CODE_ATTRIBUTES subroutine

Object::Simple define own MODIFY_CODE_ATTRIBUTES subroutine. If you use your MODIFY_CODE_ATTRIBUTES subroutine, do 'no Object::Simple;'

    package T19;
    use Object::Simple;
    
    sub m1 : Attr {}
    
    no Object::Simple; # unimport MODIFY_CODE_ATTRIBUTES
    
    # defined MODIFY_CODE_ATTRIBUTES
    sub MODIFY_CODE_ATTRIBUTES {
        my ($class, $ref, @attrs) = @_;
        # do what you want
        return;
    }
    
    sub m2 : YourAttribute {}
    
    Object::Simple->build_class;
 

AUTHOR

Yuki Kimoto, <kimoto.yuki at gmail.com>

I develope some module the following

http://github.com/yuki-kimoto/

BUGS

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

SUPPORT

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

    perldoc Object::Simple
 

You can also look for information at:

SIMILAR MODULES

Class::Accessor,Class::Accessor::Fast, Moose, Mouse, Mojo::Base

COPYRIGHT & LICENSE

Copyright 2008 Yuki Kimoto, all rights reserved.

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