What Else Does it Do?
Filesystem Layer (Badger::Filesystem
)
- Wrappers around core
File::*
modules - OO abstraction of paths, files, directories
- Flexible and extensible
Codecs (Badger::Codecs
)
- Encode and Decode stuff
- Unicode, MIME::Base64, YAML, JSON, Storable
- Wrappers around existing modules
- Consistent user interfaces (OO or functional)
- Composable units
Thus Spake Andy:
Badger also provides a filesystem layer which acts as a wrapper around Perl's
core File::*
modules. These modules do the job well enough, but have a
variety of different APIs that can make using them a bit of a minefield. The
Badger filesystem layer provides an OO abstraction of a filesystem, very much
like the most excellent Path::Class
modules. Unfortunately, Path::Class
doesn't quite provide the kind of flexibility and extensibility that I
needed for TT. I started off with a set of wrapper modules around
Path::Class
but eventually migrated to a new implementation using flyweight
objects. Here each file or directory is a simply flyweight object which stores
a path URI and a reference back to a filesystem object. All methods (e.g.
$file->read
) are delegated back to the filesystem object (e.g.
$filesystem->read_file($file->uri)
). This makes it easier to implement
filesystem extensions, like the kind of virtual filesystem that TT's
INCLUDE_PATH uses to aggregate a number of source directories into a single
virtual directory view.
Going hand-in-hand with file handling are the handy Badger::Codec
modules,
managed by the Badger::Codecs
factory module. A codec is something that
encodes and decodes data from one format to another. Each of the Badger codec
modules is a thin wrapper around another module (e.g. Encode
, Storable
,
MIME::Base64
) which provides a consistent API. You can choose to use either
an OO API (e.g. $codec->encode()
, $codec->decode()
) or a functional API
(e.g. encode()
, decode()
). The codec wrapper Does The Right Thing™ to
map it to whatever the underlying modules does (freeze()
, thaw()
, Dump()
,
to_json()
, etc). One of the nice thing that falls out of this is that
all your codecs then have the same API and can be automatically composed
into efficient codec chains that perform several encoding or decoding steps
in one.