NAME

Object::Simple - Provide new() and accessor creating methods

STATE

This module is now stable. I will not change APIs and implemetations. I will only fix bug if it is found. Version 3.0601 implementation is keeped for ever.

VERSION

Version 3.0603

SYNOPSIS

package Point;

use strict;
use warnings;

use base 'Object::Simple';

__PACKAGE__->attr(x => 0);
__PACKAGE__->attr(y => 0);

sub clear {
    my $self = shift;
    
    $self->x(0);
    $self->y(0);
}

package Point3D;

use strict;
use warnings;

use base 'Point';

__PACKAGE__->attr(z => 0);

sub clear {
    my $self = shift;
    $self->SUPER::clear();
    $self->z(0);
}

package main;

use strict;
use warnings;

my $point = Point3D->new(x => 4, y => 6, z => 5);

$point->x(1);
$point->y(2);
$point->z(5);

my $x = $point->x;
my $y = $point->y;
my $z = $point->z;

$point->clear;

FEATURES

This module has the folloing features.

1. new() and accessor creating methods is prepared.
2. Default value is available.
3. Object Oriented interface and pure perl implemetation.
4. Memory saving implementation and fast Compiling.
5. Debugging is easy.

You can think Object::Simple is Class::Accessor::Fast + "default value definition" + "useful new()"

This module's API is compatible of Mojo::Base. If you like Mojo::Base, this module is good choice.

METHODS

new

A subclass of Object::Simple can call "new", and create a instance. "new" receive hash or hash reference.

package Point;
use base 'Object::Simple';

package main;
my $book = Point->new;
my $book = Point->new(x => 1, y => 2);
my $book = Point->new({x => 1, y => 2});

"new" can be overrided to initialize the instance or arrange arguments.

Instance initialization

sub new {
    my $self = shift->SUPER::new(@_);
    
    # Initialization
    
    return $self;
}

Arguments arranging

sub new {
    my $self = shift;
    
    $self->SUPER::new(x => $_[0], y => $_[1]);
    
    return $self;
}

attr

Create accessor.

__PACKAGE__->attr('name');
__PACKAGE__->attr([qw/name1 name2 name3/]);

A default value can be specified. If dfault value is reference or object, You must wrap the value with sub { }.

__PACKAGE__->attr(name => 'foo');
__PACKAGE__->attr(name => sub { ... });
__PACKAGE__->attr([qw/name1 name2/] => 'foo');
__PACKAGE__->attr([qw/name1 name2/] => sub { ... });

Accessor is chained.

$point->x(3)->y(4);

The folloing is a sample.

package Car;
use base 'Object::Simple';

__PACKAGE__->attr(maintainer => sub { ['Ken', 'Beck'] });
__PACKAGE__->attr(handle => sub { Car::Handle->new });
__PACKAGE__->attr([qw/speed passenger/] => 0);

class_attr

Create accessor for class attribute.

__PACKAGE__->class_attr('name');
__PACKAGE__->class_attr([qw/name1 name2 name3/]);
__PACKAGE__->class_attr(name => 'foo');
__PACKAGE__->class_attr(name => sub { ... });

This accessor is called from class.

Book->title('BBB');

Class attribute is saved to $CLASS_ATTRS. This is class variable. If you want to delete or check existence of a class attribute, "delete" or "exists" function is available.

delete $SomeClass::CLASS_ATTRS->{name};
exists $SomeCLass::CLASS_ATTRS->{name};

If the class is a subclass, the class attribute is saved to $CLASS_ATTRS of subclass . See the following sample.

package Book;
use base 'Object::Simple';

__PACKAGE__->class_attr('title');

package Magazine;
use base 'Book';

package main;

Book->title('Beautiful days');
Magazine->title('Good days');

If Book->title('Beautiful days') is called, the value is saved to $Book::CLASS_ATTRS->{title}. If Magazine->title('Good days') is called, the value is saved to $Magazine::CLASS_ATTRS->{title}.

dual_attr

Create accessor for a attribute and class attribute.

__PACKAGE__->dual_attr('name');
__PACKAGE__->dual_attr([qw/name1 name2 name3/]);
__PACKAGE__->dual_attr(name => 'foo');
__PACKAGE__->dual_attr(name => sub { ... });

If the accessor is called from a package, the value is saved to $CLASS_ATTRS. If the accessor is called from a instance, the value is saved to the instance.

Book->title('Beautiful days');

my $book = Book->new;
$book->title('Good days');

OPTIONS

default

Define a default value.

__PACKAGE__->attr('title', default => 'Good news');

If a default value is a reference or object, You must wrap the value with sub { }.

__PACKAGE__->attr('authors', default => sub{ ['Ken', 'Taro'] });
__PACKAGE__->attr('ua',      default => sub { LWP::UserAgent->new });

Default value can be written by more simple way.

__PACKAGE__->attr(title   => 'Good news');
__PACKAGE__->attr(authors => sub { ['Ken', 'Taro'] });
__PACKAGE__->attr(ua      => sub { LWP::UserAgent->new });

inherit

Inherit a attribute from a base class's one.

You can inherit a class attribute from base class's one.

package BaseClass;
use base 'Object::Simple';

__PACKAGE__->class_attr('cache', default => 30, inherit => 'scalar_copy');

package SomeClass;
use base 'BaseClass';

package main;
my $obj = SomeClass->new;
$obj->cache; # This is 30, which is inherited from BaseClass's cache.

inherit option must be 'scalar_copy', 'array_copy', 'hash_copy', or sub reference. This is used to decide the way to copy the base class attribute.

The following is the implemetations to copy the value.

'scalar copy' : Normal copy        : sub { return $_[0] }
'array_copy'  : Array shallow copy : sub { return [@{$_[0]}] }
'hash_copy'   : Hash shallow copy  : sub { return {%{$_[0]}} }
sub reference : Your original copy : sub { ... }

If inherit option is specified at dual_attr(), a instance attribute inherit the class attribute.

package SomeClass;
use base 'Object::Simple';

__PACKAGE__->dual_attr('filters',
    default => sub {
        {
            trim  => sub { ... },
            chomp => sub { ... }
        }
    },
    inherit => 'hash_copy'
);

package main;
my $obj = SomeClass->new;
$obj->filters; # This is { trim => sub { ... }, chomp => sub { ... } }
               # , which is inherit from SomeClass's filters

Good example of inherit options is Validator::Custom::HTMLForm. See also this module.

PROVIDE ONLY ACCESSOR CREATING METHODS

If you want to provide only accessor creating methods, do the following way.

package YourClass;
use base 'LWP::UserAgent';

use Object::Simple 'attr';

__PACKAGE__->attr('foo');

SEE ALSO

Mojo::Base, Class::Accessor::Fast

AUTHOR

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

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

I develope this module at http://github.com/yuki-kimoto/Object-Simple

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.