$object->method1(@args1)->method2(@args2)->method3(@args3)
####
$chain = Object::MethodChain->method1(@args1)->method2(@args2)->method3(@args3);
####
$chain = Object::MethodChain->new("method1", \@args1, "method2", \@args2, "method3");
####
$chain = Object::MethodCall->method1(@args1)->method2(@args2);
####
Object::MethodCall->method1(@args1)
####
{
package Object::MethodChain;
use overload q[""], "__Set_MethodChain__";
AUTOLOAD {
my $self = shift;
my $class = ref($self) || $self;
my @new = ref($self) ? @$self : ();
our $AUTOLOAD =~ /.*::(.*)/s or
die "error: invalid method name";
push @new, {"method", $1, "args", \@_};
bless \@new, $class;
}
our $chain;
sub __Set_MethodChain__ {
$chain = $_[0];
"__Call_MethodChain__";
}
sub UNIVERSAL::__Call_MethodChain__ {
my $r = $_[0];
for my $pair (@$chain) {
my($method, $args) = @$pair{"method", "args"};
$r = $r->$method(@$args);
}
$r;
}
DESTROY {
}
}
####
{
package Object::MethodChain;
AUTOLOAD {
my $s = shift;
my $c = ref($s) || $s;
my $p = ref($s) ? $s : sub { $_[0] };
our $AUTOLOAD =~ /.*::(.*)/s or die;
my $m = $1;
my $a = \@_;
bless sub {
&$p($_[0])->$m(@$a);
}, $c;
}
DESTROY {
}
}
####
$chain = Object::MethodChain->foo;
####
sub { $_[0]->foo; }
####
{
package Object::MethodChain;
our $open_sesame = [];
AUTOLOAD {
my $self = shift;
my $class = ref($self) || $self;
my @chain = ref($self) ? &$self($open_sesame) : ();
our $AUTOLOAD =~ /.*::(.*)/s or
die "error: invalid method name";
push @chain, {"method", $1, "args", \@_};
bless sub {
if(ref($_[0]) && $open_sesame == $_[0]) {
@chain;
} else {
my $r = $_[0];
for my $pair (@chain) {
my($method, $args) = @$pair{"method", "args"};
$r = $r->$method(@$args);
}
$r;
}
}, $class;
}
DESTROY {
}
}
####
{
package Object::MethodChain;
use overload q[""], "__Set_MethodChain__";
AUTOLOAD {
my $self = shift;
my $class = ref($self) || $self;
my @new = ref($self) ? @$self : ();
our $AUTOLOAD =~ /.*::(.*)/s or
die "error: invalid method name";
push @new, {"method", $1, "args", \@_};
bless \@new, $class;
}
our $chain;
sub __Set_MethodChain__ {
$chain = $_[0];
"Object::MethodChain::__Call_MethodChain__";
}
sub __Call_MethodChain__ {
my $r = $_[0];
for my $pair (@$chain) {
my($method, $args) = @$pair{"method", "args"};
$r = $r->$method(@$args);
}
$r;
}
DESTROY {
}
}
####
{
package AnObj;
sub new {
bless [], $_[0];
}
sub foo {
print "just ";
$_[0];
}
sub bar {
$_[1] = "ack";
OtherObj->new("erl h");
}
}
{
package OtherObj;
sub new {
bless [$_[1]], $_[0];
}
sub baz {
print "anot", $_[1], $_[0][0];
"er,\n";
}
}
####
{
my $f = "foo";
my $n = AnObj->new->$f->bar(my $v)->baz("her p");
print $v, $n;
}
####
{
my $f = "foo";
my $c = Object::MethodChain->new->$f->bar(my $v)->baz("her p");
my $n = AnObj->$c;
print $v, $n;
}
####
{
my $f = "foo";
my $m = Object::MethodChain->$f->bar(my $v);
my $c = Object::MethodChain->new->$m->baz("her p");
my $n = AnObj->$c;
print $v, $n;
}
####
bless( [
{
'args' => [],
'method' => 'new'
},
{
'args' => [],
'method' => 'foo'
},
{
'args' => [
undef
],
'method' => 'bar'
},
{
'args' => [
'her p'
],
'method' => 'baz'
}
], 'Object::MethodChain' );