Design Patterns have been an on-again, off-again fad for a while now. Statements like "Perl doesn't need Design Patterns, we have the CPAN" are common because most of the well-known patterns come from Java, where you can't do much of anything without 100 lines of structural boilerplate.
But a design pattern, at it's core, is a method for solving a particular problem that can't be done using a language's native structures and can't be (elegantly) solved as a module.
For example, Class::Adapter is my CPAN module for implementing the "Adapter" pattern from the gang of four book. An Adapter may be a pattern in Java, but it doesn't really rate being called such in Perl.
So I'd like to issue this blog challenge.
I want to see a post on your favourite Perl Design Pattern, some technique or trick that can't be done elegantly with Perl's native language resources, isn't so small that it might be classed as an idiom, and can't be easily packed up into a CPAN module.
I'll happily kick things off by presenting mine, the "Constant Global" (Haskell people might call it the Curried Global, which admit has quite a ring to it)
I use it all the time for debugging and tracing.
A Constant Global is a combination of global variable and a constant which is useful for debugging, assertions, and other situations where you want to add optional functionality to a very performance-sensitive module, so a feature can be enabled (or disabled) from outside that module.
The code for the canonical debugging version looks like this...
package My::Module;
use strict;
use vars qw{$DEBUG};
BEGIN {
$DEBUG = !! $DEBUG;
}
use constant DEBUG => $DEBUG;
sub foo {
print STDERR "Running foo" if DEBUG;
}
1;
This usage allows you to define variables in your top level script or test that will turn features on or off before you load the module, without incurring the penalty of all those if (
Loading the module will look something like the following...
#!/usr/bin/perl
BEGIN {
$My::Module::DEBUG = 1;
}
use My::Module;
Now, you only get one chance to choose if a feature will be enabled or disabled, so most use cases will either be debugging, and testing special cases, or features in modules which you would never really use twice, differently, in two different places in your code.
Meta programming (Score:1)
I think Perl has continually defied these attempts to package patterns because of it's meta programmability.
Things we previously thought were not possible to package are now on CPAN as usable modules.
Design patterns are thus getting more and more refined, and in time converge simply with the best practices for the software that helps to implement them.
In the Java community metaprogramming is a much more difficult thing, so in order to produce extensible, reusable and clean code you need to have a much stric
Re: (Score:1)
bah, i meant attempts to *define*
Badger::Debug (Score:1)
I also use the $DEBUG/DEBUG idiom in pretty much every module I write. Being rather lazy I wrote Badger::Debug to do the job for me.
If you add the following to the top of your module:
package Your::Module;
use Badger::Debug default => 0;
Then you'll get both the $DEBUG package variable and DEBUG compile time constant defined for you (in this case, set to 0). The end result is almost exactly as per your example.
It also has a 'modules' option which you can use to
Higher-Order Perl as a catalog of design patterns (Score:1)
Your pattern *is* implemented in a CPAN module (Score:1)
See ifdef [cpan.org].
In response to the criticism that it is a source filter, it filters for content within pod sections, which avoids almost all of the ambiguities that otherwise make parsing Perl so fun.
Re: (Score:1)