Badger::FAQ - Frequently asked questions about Badger
It's a collection of Perl modules designed to take away some of the tedium involved in writing Perl modules, libraries and applications.
Badger started off as being all the generic bits of the Template Toolkit that weren't directly related to template processing. Things like a common base class, file handling modules, error handling, logging, and so on.
Now there are plenty of other fine modules on CPAN that do these kinds of things, including some that were my own earlier attempts at extracting useful functionality out of TT into generic modules (e.g. Class::Base, Class::Singleton, App::Config, etc). So in that sense, there's nothing particularly new or revolutionary about Badger - I've just taken a bunch of modules I've written a dozen times before for various different projects, cleaned then up, moved them into a new namespace of my own (that hopefully no-one will ever accuse me of name-squatting in), made them work with each other in a consistent way (i.e. without the mish-mash of different API styles you get whenever you plug a random selection of CPAN modules together) and released them for other people to use if they want to.
There is no Badger world order. I wrote Badger because it makes my life easier. If it makes your life easier too then I'm happy for you, but it makes no difference to me if you use it or not. I'm tired of having to justify the existence of the software that I chose to give away for free. In other words, what you see is what you get. Take it or leave it.
Badgers are smaller and can easily be recognised by their black fur and distinctive white stripe running down their snout. Moose are larger and have an impressive set of antlers. Both enjoy foraging in the forest for nuts and berries.
Joking aside, they're completely different animals. Badger is in no way intended to be a replacement or substitute for Moose or vice-versa. They were developed entirely separately with different motivations and goals. That said, they do have a lot in common.
I'll try and list some of the similarities and differences that I'm aware of. Please bear in mind that I know Badger much better than I do Moose so my knowledge may be incomplete or incorrect in places.
Some of the similarities:
Some of the differences:
In contrast Badger implements a more "regular" Perl 5 object model, albeit a a thoroughly modern one. It's got some of the metaprogramming goodness that Perl 6 amd Moose have, but not all of it. The emphasis is on providing enough metaprogramming to get the Badger job done, rather than providing a completely extensible metaprogramming environment.
To borrow the ice-cream analogy, if Perl 5's object system is vanilla, then Badger's is strawberry and Moose's is neapolitan with sprinkles and a sparkler.
One of the important principles with Badger is that you can use just one module (say, Badger::Base, Badger::Prototype or Badger::Factory) as a regular Perl 5 OO module, without having to use any of the other modules. Badger::Class provides the metaprogramming side of things to make life easy if you want it, but you can manage just fine without it.
On the other hand, Moose is all about metaprogramming. If you don't use the metaprogramming wide of things then you're not really using Moose.
Badger provides a smaller and simpler set of generic OO programming tools as part of a collection of generally useful modules for application authors (me in particular). It contains the things that I need for TT, and the kind of things that I find myself writing over and over again in pretty much every Perl project I work on. So the Moose-like (and Spiffy-like) parts of Badger are a means to an end, rather than the raison d'etre in themselves.
So to sum up, Badger and Moose do some similar things but in different ways. They both like to forage in the forest for nuts and berries. The Moose picks them off the trees and the Badger gets them off the ground.
Yes and no. Some of the wheels that I've "re-invented" were my own wheels to start with (e.g. Class::Base, Class::Singleton and Class::Facade which have been, or will soon be superceded by their Badger counterparts). Bundling them all into one place makes them easier for me to maintain and easier for the end user to find, download, install and use. It also means that they can share other core Badger modules (like Badger::Exception for error handling, for example) without having to distribute all of those separately on CPAN. Furthermore, the nature of CPAN is such that they would all end up in various different namespaces giving no real clue to the end user that they all make up part of a common toolkit.
So part of the Badger effort is about bundling up a bunch of modules that I've written (some on CPAN, some not) into a common namespace where they can play happily together. Apart from anything else, it means I only have just one CPAN distribution, test suite, set of documentation, web site, bug tracker, subversion repository, etc., etc., to deal with instead of many. In that sense we're taking existing wheels, cleaning them up, fixing any broken spokes and putting new tyres on. It's as much about packaging and presentation as it is about functionality.
Having said that, there is some duplication between Badger modules and existing CPAN modules that can do the same things just as well or even better. In some cases that is an unavoidable consequence of the length of time that Badger was in gestation. I've been developing the code base for TT3/Badger on and off since 2001. Many of the fine CPAN modules that people take for granted these days weren't around back then so I started by rolling my own. This code then made its way into other projects and evolved over time to where it is now. Having invested a lot of time in the code, test suite and documentation, I know exactly where I am with it and I can be very productive using it. So while it's not broken, I don't plan to fix it.
In other cases, the choice to re-invent a wheel was deliberate because the existing wheels weren't a good fit for what I wanted or needed. For example, the Path::Class modules do a fantastic job of providing an OO interface to a filesystem. I worship the ground that Ken Williams walks on for saving me the torment of having to deal with all the different File::* modules directly.
Unfortunately the Path::Class modules don't provide the level of abstraction that is required for them to work with virtual filesystems (such as I require for TT). Adapting them turned out to be a futile effort because they're essentially just very simple and elegant wrappers around the various File::* modules. I needed a similarly simple wrapper, but of a slightly different kind. So I rolled my own, borrowing Ken's (and other people's) ideas and/or bits of code wherever I could. That's the second best kind of code re-use - don't re-invent a wheel, just copy someone else's (just as long as you've also got something new to add).
Another example is the Badger::Exporter module. It does pretty much exactly what the Exporter module does, except that it works with class inheritance and has some methods of convenience to make it more friendly to use. I could have written it as a wrapper around Exporter (and that's what I started doing) but in the end, it was easier to cut and paste the dozen or so critical lines from Exporter and build the module how I wanted from scratch instead of trying to cobble OO on top a procedural module and confuse everyone (myself included) in the process.
So in summary, yeah, but no, but.
Badger doesn't really re-invent any wheels but adapts a few to fit into this particular niche.
Andy Wardley <firstname.lastname@example.org>
Copyright (C) 2008-2012 Andy Wardley. All Rights Reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.