M
Matija Papec
It seems that functional approach is better suited for smaller "classes"
compared to classical OOP. Thinking in such way is challenging and pretty
new to me so I would be interested to hear suggestions; eg. is there some
flaw which can show in threading environment or how to optimize this very
basic OO example below.
===========================
use strict;
use warnings;
my $obj = Child(foo => 1, bar =>2);
$obj->(addcond => [id => 7]);
$obj->(addcond => [name => "lucas"]);
print $obj->(dumper => 1) if $obj->(can => "dumper");
sub Child {
#
# child class
#
our ($AUTOLOAD, $SUPER);
# child object data
my @foobar;
my $m = {
AUTOLOAD => sub {
my $self = shift;
print "There is no $AUTOLOAD!\n";
return;
},
dumper => sub {
my $self = shift;
$SUPER->(dumper => @_);
},
addcond => sub {
my $self = shift;
# get $SUPER via $self
# $AUTOLOAD contains current method name
$self->("SUPER")->($AUTOLOAD => @_);
},
};
return newclosure(usebase => \&Parent, $m, @_);
}
sub Parent {
#
# parent class
#
use Data:umper;
# object data
my %arg = @_;
my @cmdcond;
my $m = {
dumper => sub {
my $self = shift;
Dumper \@cmdcond, \%arg;
},
addcond => sub {
my $self = shift;
push @cmdcond, shift;
},
};
return newclosure($m, @_);
}
#########################################
sub newclosure {
#
our ($AUTOLOAD, $SUPER);
my $m = shift;
my $usebase;
my $super;
# inheritance?
if ($m eq "usebase") {
$usebase = shift;
$m = shift;
$super = &$usebase;
}
# core methods
$m->{SUPER} = sub { $super };
$m->{can} = sub {
my $self = shift;
my $sub = shift;
$m->{$sub} || $super->(can => $sub) || $m->{AUTOLOAD};
};
my $self;
return $self = sub {
my $sub = shift;
local $AUTOLOAD = $sub;
local $SUPER = $super;
# who you gonna call?
return
$m->{$sub} ? $m->{$sub}->($self, @_) :
$super->(can => $sub) ? $super->($sub, @_) :
$m->{AUTOLOAD}->($self, @_);
};
}
compared to classical OOP. Thinking in such way is challenging and pretty
new to me so I would be interested to hear suggestions; eg. is there some
flaw which can show in threading environment or how to optimize this very
basic OO example below.
===========================
use strict;
use warnings;
my $obj = Child(foo => 1, bar =>2);
$obj->(addcond => [id => 7]);
$obj->(addcond => [name => "lucas"]);
print $obj->(dumper => 1) if $obj->(can => "dumper");
sub Child {
#
# child class
#
our ($AUTOLOAD, $SUPER);
# child object data
my @foobar;
my $m = {
AUTOLOAD => sub {
my $self = shift;
print "There is no $AUTOLOAD!\n";
return;
},
dumper => sub {
my $self = shift;
$SUPER->(dumper => @_);
},
addcond => sub {
my $self = shift;
# get $SUPER via $self
# $AUTOLOAD contains current method name
$self->("SUPER")->($AUTOLOAD => @_);
},
};
return newclosure(usebase => \&Parent, $m, @_);
}
sub Parent {
#
# parent class
#
use Data:umper;
# object data
my %arg = @_;
my @cmdcond;
my $m = {
dumper => sub {
my $self = shift;
Dumper \@cmdcond, \%arg;
},
addcond => sub {
my $self = shift;
push @cmdcond, shift;
},
};
return newclosure($m, @_);
}
#########################################
sub newclosure {
#
our ($AUTOLOAD, $SUPER);
my $m = shift;
my $usebase;
my $super;
# inheritance?
if ($m eq "usebase") {
$usebase = shift;
$m = shift;
$super = &$usebase;
}
# core methods
$m->{SUPER} = sub { $super };
$m->{can} = sub {
my $self = shift;
my $sub = shift;
$m->{$sub} || $super->(can => $sub) || $m->{AUTOLOAD};
};
my $self;
return $self = sub {
my $sub = shift;
local $AUTOLOAD = $sub;
local $SUPER = $super;
# who you gonna call?
return
$m->{$sub} ? $m->{$sub}->($self, @_) :
$super->(can => $sub) ? $super->($sub, @_) :
$m->{AUTOLOAD}->($self, @_);
};
}