Badger::Class
- Objects for manipulating classes
- Classes are OO packages
- Access to symbol table
- Metaprogramming methods
- Hygienic class construction
Thus Spake Andy:
The next level up above the class methods is the metaprogramming layer.
This brings us to Badger::Class
. This defines a class of objects which
act as wrappers around Perl packages. Remember that a Perl package is
the particular implementation of the OO concept of a class, and that
packages are really just symbol tables. The terminology isn't that important
as in most cases class
is synonymous with package
which is the same
thing as a symbol table
. But not quite.
A Badger::Class
object allows you to set/get entries in the symbol table
for a package (package variables, constants, methods, etc). It also provides
higher-level metaprogramming methods. For example, there's a method to set
the base class for a module which loads the module and adds it to @ISA
(just like use base
but implemented as a method rather than a separate
module - less modules, faster startup).
Let me see if I can explain what I mean by hygienic class construction.
Let's say you're writing a module and you need some accessor methods in your
class. So you make Class::Accessor
(or something similar) a base class
of the module and then call the mk_accessors
method to construct your
accessor methods. Now modules like Class::Accessor
quite rightly do one
thing and do it well. But your module needs to do several things, so you
add a bunch more base classes and call all of their respective methods to
construct the other parts you need. The problem with this is that your
module namespace has now been polluted by all of the methods that these
modules implement. That includes all of the methods that you never used or
required but got bundled in anyway. If two or more of the base classes
implement the same method then you're in a world of pain. This might not
even be obvious - for example, two of your base class modules could implement
their own internal _error()
method to report errors. Worse still, all of
these class methods are also available as object methods. That means that
every object you create will have a mk_accessors()
method, which you almost
certainly don't want. You can use namespace::clean
to help you out of the
mess, but that's really just addressing the symptoms and not the root cause.
The approach that Badger uses is to construct your new module class remotely.
Instead of adding functionality to your class that you then invoke to
have your module bootstrap itself, you create a Badger::Class
object
to do it for you from a distance. A Badger::Class
object is a wrapper
around your class's symbol table and implements methods to help manipulate
the symbol table (e.g. to define methods, constants, package variables, etc).
You can add as many different methods to the Badger::Class
module (or a
subclass of it) as you like because they never get added to the target
symbol table. Hence, no pollution of your classes.