NAME
Simo - Very simple framework for Object Oriented Perl.
VERSION
Version 0.01
FEATURES
Simo is framework that simplify Object Oriented Perl.
The feature is that
- 1.You can write accessors in very simple way.
- 2.Inheritable new method is prepared.
- 3.You can set default value and hook function for accessors
If You use Simo, you are free from bitter work writing new and accessors repeatedly
SYNOPSIS
package Book;
use Simo;
# simple accessors
sub title{ ac }
# having default value
sub author{ ac 'Kimoto' }
# all accessor option
sub description{ ac
default => 'This is good book',
set_hook => sub{
my ( $self, $val ) = @_;
# do what you want to do
return $val;
},
get_hook => sub{
my ( $self, $val ) = @_;
# do what you want to do
return $val;
},
hash_force => 1
}
1;
DESCRIPTION
Creating class and accessors
You can create class and accessors.
package Book;
use Simo;
# accessors
sub title{ ac }
sub author{ ac }
sub description{ ac }
1;
This sample create Book class and three accessor mothods( title,author and description ), and new method is automatically created.
Using class and accessors
You can use Book class. use Book;
# constructor
my $book = Book->new(
title => 'Happy book',
author => 'Ken',
description => 'this give you happy',
);
# get value
my $title = $book->title; # 'Happy book'
# set value
$book->author( 'Taro' );
You can pass key-value pairs to new method. Key is need to be same name as accessor.
If you pass nonexistent key, script will die.
you can get value :
$book->title;
you can set value :
$book->title( 'Taro' );
Get old value
You can get old value when you use accessor as setter.
$book->author( 'Ken' );
my $old_value = $book->author( 'Taro' ); # $old_value is 'Ken'
accessor having Default value
You can set default value for accessor.
package Book;
use Simo;
sub title{ ac 'Papa' }
You get 'Papa' if 'title' field is not initialized.
Setter Hook function for validation or filter or etc.
You can set set_hook function for accessor.
package Book;
use Simo;
# set_hook function for accessor
sub date{ ac set_hook => \&date_filter }
# set_hook function definition
sub date_filter{
my ( $self, $val ) = @_;
$val =~ s/-//g; # ( '2008-10-10' -> '20081010' )
return $val;
}
1;
If you set date this way $book->title( '2008-08-11' );
'2008-08-08' is filtered, and change to '20080811'.
set_hook function arguments and return value
set_hook function receive two args( $self and $val ).
In this example, $self is $book object.
$val is passed value '2008-08-11'
if you pass array to setter, $val has been converted to array ref.
and you must return scalar, not list.
Getter Hook function for initialization or etc.
You can set get_hook function for accessor.
package Book;
use Simo;
# get_hook function for accessor
sub date{ ac
get_hook => sub{
my ( $self, $val ) = @_;
if( !$val ){ # val is $self->{ 'conf' }
$val = localtime;
$self->date( $val ); # if you set
}
return $val;
}
}
1;
you get date
$book->date;
if $book->{ 'date' } is undef, $book->date return current localtime.
get_hook option is useful, if you want to set default value in dynamically, not Statically.
get_hook function arguments and return value
get_hook function receive two args( $self and $val ).
In this example, $self is $book object.
$val is current value undef.
and you must return scalar, not list.
Automatically type convert
If you pass array to accessor, array convert to array ref. $book->title( 'a', 'b' ); $book->title; # get [ 'a', 'b' ], not ( 'a', 'b' )
Accessor option
You can set accessor option.
default option
You can set default value for accessor.
sub author{ ac 'Kimoto' }
or explicitely
sub author{ ac default => 'Kimoto' }
set_hook option
You can define hook function for setter
sub date{ ac set_hook => \&filter }
sub filter{
my ( $self, $val ) = @_;
# ...
return $some_val;
}
or using anonymous function
sub data{ ac
set_hook => sub{
my( $self, $val ) = @_;
# ...
return $some_val;
}
}
get_hook option
You can define hook function for getter
sub date{ ac
get_hook => sub{
my ( $self, $val ) = @_;
if( !$val ){ # val is $self->{ 'conf' }
$val = localtime;
$self->date( $val ); # if you set
}
return $val;
}
}
hash_force option
If you pass array to accessor, Normally list convert to array ref. $book->title( 'a' , 'b' ); # convert to [ 'a', 'b' ]
Even if you write $book->title( a => 'b' )
( a => 'b' ) converted to [ 'a', 'b' ]
If you use hash_force option, you convert list to hash ref
sub country_id{ ac hash_force => 1 }
$book->title( a => 'b' ); # convert to { a => 'b' }
Multiple accessor option setting sample
# one line
sub title{ ac 'Pure love', hook => \&filter, hash_force => 1 }
sub filter{
# ..
}
# multiple line, hook function is anonimous
sub title{ ac { k => 1 },
hash_force => 1,
hook => sub {
# ..
}
}
# multiple line, default is explicitely, hook function is anonimous
sub title{ ac
default => { k => 1 },
hash_force => 1,
hook => sub {
# ..
}
}
scalar context and list context
You can call accessor in scalar context and list context.
Accessor is designed to suit context.
You call accessor in scalar context, you get scalar value( scalar, array ref, hash ref, object, etc )
my $ary = $book->authors; # you get array ref
You calls accessor in list context, you get list.
my @ary = $book->authors; # you get list
EXPORT
This class exports ac function. you can use ac function to implement accessor.
FUNCTIONS
ac
You can define accsessor using ac function.
package Book;
use Simo;
sub title{ ac }
...
You can use this accessor.
Get is $book->title;
Set is $book->title( 'Bird Adventure' );
new
New method is created automatically. it receive key-value pairs as args.
my $book = Book->new( title => 'PaPa is good', author => 'MaMa' );
MORE TECHNIQUES
I teach you useful techniques.
New method overriding
by default, new method receive key-value pairs. But you can change this action by overriding new method.
For example, Point class. You want to call new method this way.
my $point = Point->new( 3, 5 ); # xPos and yPos
You can override new method.
package Point;
use Simo;
sub new{
my ( $self, $x, $y ) = @_; # two arg( not key-value pairs )
# You can do anything if you need
return $self->SUPER::new( x => $x, y => $y );
}
sub x{ ac }
sub y{ ac }
1;
Simo implement inheritable new method. Whenever You change argments or add initializetion, You override new method.
Extend base class
you may want to extend base class. It is OK.
But I should say to you that there are one thing you should know. The order of Inheritance is very important.
I write good sample and bad sample.
# base class
package Book;
sub title{ ac };
# Good sample.
# inherit base class. It is OK!
package Magazine;
use base 'Book'; # use base is first
use Simo; # use Simo is second;
# Bad sample
package Magazine;
use Simo; # use Simo is first
use base 'Book'; # use base is second
If you call new method in Good sample, you call Book::new method. This is what you wanto to do.
If you call new method in Bad sample, you call Simo::new method. you will think why Book::new method is not called?
Maybe, You will be wrong sometime. So I recomend you the following writing.
package Magazine; use base 'Book'; # package and base class
use Simo;
It is like other language class Definition and I think looking is not bat. and you are not likely to choose wrong order.
AUTHOR
Yuki Kimoto, <kimoto.yuki at gmail.com>
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=Simo. 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 Simo
You can also look for information at:
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
SEE ALSO
Class::Accessor,Class::Accessor::Fast, Moose, Mouse.
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.