bennymack has asked for the wisdom of the Perl Monks concerning the following question:
Hello Monks of the Monastery,
It's time for the latest installation of bennymack creations.
Today's creation is difficult to name so I'll just try to explain what it does. The problem it attempts to solve is when you have two subs that are slightly different but mostly the same. The difference between the two subs might be just one line.
So, you could copy and paste the sub into two separate subs then maintain them both and just work around the differences. Or you can come up with a way to have both subs live together and programmatically, in as hygenic a manner as possible, alter them as needed. Time for some example code.
################# UseEvalAttributes2.pm package UseEvalAttributes2; use strict; use warnings; use EvalAttributes( qw[CONDITION NAME] ); BEGIN { our @ISA = qw[EvalAttributes]; } INIT { *sub1 = macro_sub( CONDITION => 0, NAME => 'sub1' ); *sub2 = macro_sub( CONDITION => 1, NAME => 'sub2' ); } sub macro_sub : Macro( qw[CONDITION NAME] ) { print NAME . " COMMON CODE\n"; print NAME . " CONDITIONAL CODE\n" if CONDITION; return; } 1; __END__ $ perl -Mstrict -Mwarnings -MB::Deparse -e ' use UseEvalAttributes2; UseEvalAttributes2::sub1(); UseEvalAttributes2::sub2(); print "sub ", B::Deparse->new()->coderef2text( \&UseEvalAttributes2::s +ub1 ), "\n"; print "sub ", B::Deparse->new()->coderef2text( \&UseEvalAttributes2::s +ub2 ), "\n"; ' sub1 COMMON CODE sub2 COMMON CODE sub2 CONDITIONAL CODE sub { package EvalAttributes; BEGIN {${^WARNING_BITS} = "UUUUUUUUUUUU"} use strict 'refs'; local *__ANON__ = 'EvalAttributes::Macro::new_referent'; package UseEvalAttributes2; print "sub1 COMMON CODE\n"; '???'; return; } sub { package EvalAttributes; BEGIN {${^WARNING_BITS} = "UUUUUUUUUUUU"} use strict 'refs'; local *__ANON__ = 'EvalAttributes::Macro::new_referent'; package UseEvalAttributes2; print "sub2 COMMON CODE\n"; print "sub2 CONDITIONAL CODE\n"; return; }
I hope the results are clear and more or less speak for themselves. I'm leaving out implementation details for now as they're not overly pretty. I like this approach over other subref/closure/variable/conditional approaches because it compiles only the code you absolutely need so there's no execution overhead. It's all determined when the subs are manufactured.
My questions are, as usual, is it worthwhile? What would be a better way to do it? Can I leverage an existing CPAN module for this purpose? OR am I just an idiot...
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Data driven programming? Not sure.
by GrandFather (Saint) on Apr 01, 2007 at 04:16 UTC | |
Re: Data driven programming? Not sure.
by dk (Chaplain) on Apr 01, 2007 at 04:55 UTC |