- 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.
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
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
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.