NAME
Simo::Manual - Simo Manual
CAUTION
Now writing.
Please wait.
DESCRIPTION
Accessor options
default option
You can define default value of attribute.
sub title{ ac default => 'Perl is very interesting' }
constrain option
you can constrain setting value.
sub price{ ac constrain => sub{ /^\d+$/ } }
For example, If you call $book->price( 'a' ), this call is die, because 'a' is not number.
'a' is set to $_. so if you can use regular expression, omit $_.
you can write not omiting $_.
sub price{ ac constrain => sub{ $_ > 0 && $_ < 3 } }
If you display your message when program is die, you call craok.
use Carp;
sub price{ ac constrain => sub{ $_ > 0 && $_ < 3 or croak "Illegal value" } }
and 'a' is alse set to first argument. So you can receive 'a' as first argument.
sub price{ ac constrain => \&_is_number }
sub _is_number{
my $val = shift;
return $val =~ /^\d+$/;
}
and you can define more than one constrain.
sub price{ ac constrain => [ \&_is_number, \&_is_non_zero ] }
filter option
you can filter setting value.
sub description{ ac filter => sub{ uc } }
setting value is $_ and frist argument like constrain.
and you can define more than one filter.
sub description{ ac filter => [ \&uc, \&quoute ] }
trigger option
You can define subroutine called after value is set.
For example, issue_datetime is set, issue_date is update.
$self is set to $_ and $_[0] different from constrain and filter.
sub issue_datetime{ ac trigger => \&update_issue_date }
sub issue_date{ ac }
sub update_issue_date{
my $self = shift;
my $date = substr( $self->issue_datetime, 0, 10 );
$self->issue_date( $date );
}
and you can define more than one trigger.
sub issue_datetime{ ac trigger => [ \&update_issue_date, \&update_issue_time ] }
read_only option
Read only accessor is defined
sub get_size{ ac default => 5, read_only => 1 }
Accessor name should be contain 'get_'.If not, warnings is happen.
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' }
Order of constrain, filter and trigger
- 1. val is passed to constrain subroutine.
- 2. val is passed to filter subroutine.
- 3. val is set
- 4. trigger subroutine is called
|---------| |------| |-------|
| | | | | |
val-->|constrain|-->|filter|-->(val is set)-->|trigger|
| | | | | |
|---------| |------| |-------|
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'
MORE TECHNIQUE
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.
new_self_and_parent
new_self_and_parent resolve the inheritance of no Simo based class;
# no Simo based class
package Book;
sub new{
my ( $proto, %args ) = @_;
my $class = ref $proto || $proto;
my $self = {};
bless $self, $class;
$self->{ title } = $args{ title };
$self->{ author } = $args{ author };
return $self;
}
package Magazine;
use Simo( base => 'Book' );
sub price{ ac }
sub description{ ac }
sub new{
my ( $self, @args ) = @_;
return $self->new_self_and_parent( @args, [ 'title', 'author' ] );