Class::Accessor::Chainedを遊んでみる

DBIx::ClassをインストールしてたらClass::Accessor::Chainedなるものを発見(*゚Д゚)ムホムホ

http://search.cpan.org/~rclamp/Class-Accessor-Chained/

サンプルコード

./test.pl


#! /usr/bin/perl
use strict;
use warnings;
use NekoChained;
my $n = NekoChained->new->foo(1)->bar(3)->baz(5);
print $n->foo,"\n";
print $n->bar,"\n";
print $n->->baz,"\n";
$n->foo(2)->bar(4)->baz(6);
print $n->foo,"\n";
print $n->bar,"\n";
print $n->baz,"\n";

./NekoChained.pm


package NekoChained;
use strict;
use warnings;
use base qw(Class::Accessor::Chained);
__PACKAGE__->mk_accessors(qw( foo bar baz ));
1;

実行結果


% ./test.pl
1
3
5
2
4
6
%

こんな感じになります。
Class::Accessor::Chained::Fastでも基本同じことができますが、Class::AccessorとClass::Accessor::Fastの違いと同じくFastは速度重視です。
Class::Accessor::Chainedの実装が


sub make_accessor {
my($class, $field) = @_;
# Build a closure around $field.
return sub {
my($self) = shift;
if (@_) {
$self->set($field, @_);
return $self;
}
else {
return $self->get($field);
}
};
}

なのに対し、
Class::Accessor::Chained::Fastの実装は


sub make_accessor {
my($class, $field) = @_;
return sub {
my $self = shift;
if(@_) {
$self->{$field} = (@_ == 1 ? $_[0] : [@_]);
return $self;
}
return $self->{$field};
};
}

と、setメソッドやgetメソッドを使ってません。
Class::Accessor::Fastの実装は


sub make_accessor {
my($class, $field) = @_;
return sub {
return $_[0]->{$field} unless @_ > 1;
my $self = shift;
$self->{$field} = (@_ == 1 ? $_[0] : [@_]);
};
}

違いというとreturn $self;するかどうか。
return $self;することによりChaineを実現させてますねぇ。

fooに1を設定


my $n = NekoChainedFast->new->foo(1);

fooをprintすると、


print $n->foo,"\n";

1が表示される。
barに2を設定。


$n->bar(2);

barをprintすると、


print $n->bar,"\n";

2が表示される。

fooに3、barに4を一気に設定


$n->foo(3)->bar(4);

fooとbarをprintすると


print $n->foo,"\n";
print $n->bar,"\n";

3、4が表示される。

こんなのですた。