A recent contribution to CPAN is Class::MixinFactory by simonm . Here we show two more ways to do the same thing in addition to the ones that Simon lists in the SEE ALSO section.
One method relies on Leon Brocard's Language::Functional. The other relies on Toby Ovod-Everett's Class::Prototyped
I include here a file, which when run, produces output similar to the output from factory_class.t the Class::MixinFactory distribution.
It shows two new ways of doing this, the Language::Functional approach and the Class::Prototyped approach.
use strict; use Language::Functional ':all'; sub _uc { uc shift } ; sub bold { sprintf "<b>%s</b>", shift } ; sub italics { sprintf "<i>%s</i>", shift } ; my @telescope = (\&_uc, \&bold, \&italics) ; my $o = foldl { my $seed = shift; my $func = shift; $func->($seed) } "hello, world!", \@telescope; warn $o; # begin prototyped version ------------------------------------------- +------- use Class::Prototyped ':EZACCESS'; my $po; $po = Class::Prototyped->new ( uc_m => sub { uc $_[1] }, italics_m => sub { italics $_[1] }, bold_m => sub { bold $_[1] } ); my @agenda = qw(uc_m italics_m); my @agenda2 = qw(bold_m italics_m uc_m); my $ret = foldl { my $seed = shift; my $meth = shift; $po->$meth($seed +) } "hello, world!", \@agenda; warn $ret; $ret = foldl { my $seed = shift; my $meth = shift; $po->$meth($seed) } + "hello, world!", \@agenda2; warn $ret;
We can compare these two implementations in a number of ways - readability, dynamic utility, object power, and sub power.
Of the two implementations, the functional implementation is the easiest to read and follow.
The prototype implementation appears to be easier to manipulate dynamically. What I mean by easier to manipulate dynamically is that all one need do is specify a list of strings in order to build up a sequence of operations. Strings can come from many places, such as form data, databases, STDIN, etc. With the functional version, you would need to build yourself a dispatch table in order to get similar functionality. The table building is an intrinsic aspect of using Class::Prototyped. It must be done manually for the functional version.
Prototyped objects are powerful and flexible. They give one the advantage of objects without all the class-building. The functional version will not have the advantages of prototyped objects without creating objects and then references to the subroutines of those objects (I don't even know if that is possible).
An advantage of the functional implementation is that you can use normal monadic functions just by passing a reference to them. With the prototyped implementation, you have to create an object wrapper for them.
Perl offers a wealth of ways to solve problems. Simon's recent Class::MixinFactory solved a number of problems with the Mixin approach to runtime generation of "agendas for mixing behavior." He also makes mention of a number of other approaches and perhaps should mention the Class::Delegation manpage in addition.
In this article, I have shown two more ways to mix behavior. The actual one to choose for software design remains open based on other aspects of the intended application.
2004-12-06 Janitored by Arunbear - added readmore tags, as per Monastery guidelines
Considered by DaWolf: "Promote to tutorial? Edit = Yes|Keep = No." Vote tally (Keep/Edit/Delete) = 17/20/0.
Unconsidered by davido: No prevailing consensus in the vote after several days.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: alternate approaches to mixing behavior using Language::Functional and Class::Prototyped
by dragonchild (Archbishop) on Dec 06, 2004 at 14:10 UTC |