Sometimes a closure is an object waiting to happen. (And sometimes the reverse.) Consider:
That defines your base class, where all the common code can live.package Encoder; ## Basic constructor sub new { my $type = shift; my $self = {}; bless $self, $type; } ## Define the common interface sub shared_stuff { return reverse $_[1]; } ## Define the uncommon interface sub other_stuff { die "Somebody didn't define the other stuff!"; } ## Generalized encoding method sub encode { my $self = shift; my ($text) = @_; $self->common_stuff($text); $self->other_stuff($text); }
Then, for each kind of encoder, you can define a subclass. For many subclasses, they'll be doing the same overall thing with variations, and you can just redefine the 'other_stuff' method. Otherwise, you can redefine 'encode' itself... but you'll still have 'common_stuff' to call if you want it.
# In Encoder/B.pm package Encoder::B; use base 'Encoder'; sub other_stuff { my ($text) = @_; my $new_text = $text; $new_text =~ s/a/c/g; }
Then, finally, you only need a factory subroutine to create the right type of encoder for each user preference:
use Encoder::B; use Encoder::Whatever; our %Encoder_Table => ( 'b' => 'Encoder::B', 'c' => 'Encoder::Whatever', ); sub encoder_factory { my ($e) = @_; exists $Encoder_Table{$e} or die "'$e' is not a valid type of encoder, sorry!"; return $Encoder_Table{$e}->new(); }
And, finally, to get your new encoder and use it:
There will be a speed hit, but it'll be faster than doing constant per-word checks, and easier to keep organized than closures-upon-closures-upon-closures.my $encoder = encoder_factory($whatever_e_is); print $encoder->encode("Hahahaha!");
Note: Code is untested and I've been drinking Cabernet.
stephen
In reply to Re: Building an anonymous subroutine
by stephen
in thread Building an anonymous subroutine
by BorgCopyeditor
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |