On Saturday, December 4, 2004, at 09:18 PM, Terrence Brannon wrote:
A recent contribution to CPAN is Class::MixinFactory by Simon Cavaletto.
Here we show two more ways to do the same thing in addition to the ones
that Simon lists in the SEE ALSO section.
Terrence -- Thanks for your article, and for your attention to this issue.
However, I'm not convinced that these alternatives "do the same thing" as Class::MixinFactory on other than a very abstract level.
Both of the examples use foldl() to chain several function calls together, but they don't do any of the following:
1. Create polymorphic instances, which hide different behaviors behind an identical-looking simple calling interface;
2. Allow behaviors for several functions to be grouped together, so that one user-selectable option can influence multiple methods;
3. Allow behaviors to control how items later in the chain are called, so that they can wrap them in an eval, cache the results, do something before the call and then clean up after, etc.
Issue 1 is fairly easy to address, by replacing the foldl call with a call to a dynamically built single function that calls a selection of others, and I've included some sample code in a post-script below that extends your examples in this way.
But issues 2 and 3 are harder to address using the approaches you've shown. Issue 3 in particular seems to mandate some type of explicit redispatch mechanism as opposed to simple pipelining of function results.
Using Class::Prototyped and multiple parents does allow you to solve issue 2; each collection of behaviors can be made into a prototyped object and then your instances can specify some selection of them as parents. However, to support the wrapper methods for issue 3, you'd need to add support for NEXT-style redispatch, as Class::Prototyped only implements an equivalent to SUPER.
He also makes mention of a number of other approaches and
perhaps should mention Class::Delegation in addition.
Thanks; I'll add that to the "RELATED MODULES" section of the ReadMe.pod.
-Simon
----------------------------------------------------------------------
# POST-SCRIPT WITH EXAMPLES
Rather than requiring callers to go through the foldl() rigamarole, I'd much rather hide this implementation behind a simple function-call or method-call interface.
It's easy to construct curried functions:
sub build_func {
my @funcs = @_;
sub {
my $seed = shift;
$seed = $_->( $seed ) foreach ( @funcs );
$seed;
}
}my $viewer_1 = build_func(\&_uc, \&bold, \&italics);
my $viewer_2 = build_func(\&italics, \&bold);
warn $viewer_1->("hello, world!");And using Class::Prototyped, you could create instances that had those curried functions installed as methods.
sub build_method {
my @methods = @_;
sub {
my ( $self, $seed ) = @_;
$seed = $self->$_( $seed ) foreach ( @methods );
$seed;
}
} my $views = Class::Prototyped->new(
uc_m => sub { uc $_[1] },
italics_m => sub { italics $_[1] },
bold_m => sub { bold $_[1] }
); my $viewer_1 = Class::Prototyped->new(
'*' => $views,
'view' => build_method( qw/ uc_m bold_m italics_m / ),
); my $viewer_2 = Class::Prototyped->new(
'*' => $views,
'view' => build_method( qw/ italics_m bold_m / ),
); warn $viewer_1->view("hello, world!");
_______________________________________________ sw-design mailing list [EMAIL PROTECTED] http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
