Baldrick::Turnip

From CunningPlans

Jump to: navigation, search

Contents

[edit] package Baldrick::Turnip

Baldrick::Turnip is the fundamental object class from which all other objects in the Baldrick Application Framework are derived. It contains utility functions for such common activities as lookup up configuration file items, logging, and error handling. All classes with the Baldrick:: namespace prefix are derivatives of Baldrick::Turnip.

[edit] Interface

[edit] Lifecycle Methods

[edit] new()
sub new( $class, %args-as-for-init, [ no_init => 0|1 ] )
  • $class - package name, used in the same way as any perl constructor.
  • no_init => 0 | 1 -- if nonzero, $self->init() will NOT be called.
  • %args-for-init -- if any arguments are present (except no_init), they will be passed to $self->init().
  • force_init => 0 | 1 -- if %args-for-init might be empty, you can use this meaningless dummy parameter 'force_init' to ensure that init() is called.
This generic constructor is shared by all classes that inherit from Turnip. Like any other constructor, it creates and blesses a hash. If any arguments are present (other than no_init=>true), new() will immediately call init() with those arguments. init() is expected to do all the work of a constructor other than blessing.
Baldrick often bypasses new. new() is never called for objects created with Baldrick::Util::createObject(), by Baldrick::Database::query(), or by SpecialTurnip factory methods. Instead, these object-creation methods bless a hash (which could be obtained from DBI, a config file, or any of several other sources) and then call init() on it. Thus, all essential constructor functionality must be in init().

Best practices:

  • never override new()
  • put all constructor logic in init()
  • when you use new(), always pass at least one parameter to it to ensure init() is called.

[edit] init()

sub init( %args ) return $self
  • copyRequired => [ qw(var1 var2 var3...) ] -- every parameter name in the copyRequired listref must be present in the argument list for init(), otherwise a fatal error results. The variable name and its associated value are copied into $self, with the variable name preceded by an underscore.
  • copyOptional => [ qw(var1 var2 var3...) ] -- like copyRequired, except that no fatal error is raised. Missing values will be obtained from copyDefaults (see below), or not defined. (copyOptional is deprecated in favour of copyDefaults).
  • copyDefaults => { var1 => val1, var2 => val2, ... } -- source of values for copyOptional. If copyOptional is missing, as is usually the case, then the 'keys' list of copyDefaults will be used instead of copyOptional(). For each variable listed here, the corresponding value will be pulled from the argument list of init() if present, otherwise from the copyDefaults hash(), and put into $self with the variable name prefixed with '_'.
  • logHandle => FileHandle object -- to be copied into $self->{_logHandle} if present, and thereafter used by writeLog().
  • logprefix => text -- this prefix is used for writeLog(). If not defined, ref($self) is used.
  • openLogFile => filename -- if present, then this filename will be opened for appending and its handle stored as $self->{_logHandle}
  • creator => Baldrick::Turnip object. If defined:
    • creator->getLogHandle() is called, and if a non-null result is returned, this becomes self's logHandle().
    • creator->getConfigRoot() is copied to $self->{_config}, only if arg copyConfig is present. deprecated
init() is intended to do most of the work of constructing. Constructors are often bypassed (as it is a common practise in Baldrick to create a hash, perhaps with database results, then bless it, bypassing new()), thus this serves as a surrogate constructor. Subclasses are free to define their own arguments to init(), expecting only that it will be called immediately after construction or blessing).
All classes derived from Baldrick::Turnip() should implement a custom init() method.
If Baldrick::Turnip is not the immediate ancestor, but another Turnip-derived class is the parent, then the descendant class should first call $self->SUPER::init(%args) without passing any copyRequired or copyDefaults to it. This allows the parent class to supply its own copyRequired and copyDefaults to its own parent.
Next, the derived class's init() should call $self->SUPER::init(%args, copyRequired => [ ...], copyDefaults => { ... }), in order to initialise its own required/optional fields.
Custom constructor logic should follow.
init should end with 'return $self->analyse(%args)'. analyse() will return $self.

[edit] analyse()

sub analyse()
analyse() is intended to set up derived members, perform consistency checks, etc. The convention is to call it at the end of init(), and whenever a state change is thought to have happened. analyse() can be called any number of times in an object's lifetime; it should do whatever it needs to do quickly, and not rely on such things as database connections being available to the object.
The analyse() of Baldrick::Turnip does nothing at all; derived classes are expected to do something useful here.

[edit] analyze()

sub analyze()
This is a simple wrapper for analyse(), allowing it to be called with an alternate spelling.

[edit] DESTROY()

calls closeLog().

[edit] _construct()

sub _construct( \%source, $varlist, %opts )
A utility function that aids in constructing an object. Given a list of variables ($varlist), copy each from %source into $self, with the prefix '_' to indicate private member status.
  • required parameters:
    • \%source : usually the %args of init()
    • \@varlist : a list of variables to look for in \%source and copy (with associated values) into $self. Each variable name will be prefixed with '_'. If any are undefined, the resulting behaviour is controlled by some of the %opts that follow.
  • optional parameters in %opts:
    • defaults => \%hashref - default values to be used if \%source doesn't contain an element from \@varlist
    • required => 0|1 - if a variable from \@varlist is undefined in both \%source and 'defaults', give a fatal error if required is true.

Example:

   sub init()
   {
       my ($self, %args) = @_;
       $self->_construct(\%args, [ qw(config id name) ], required => 1);
       $self->_construct(\%args, [ qw(bloodtype shoesize) ], defaults => { bloodtype => 'O-', shoesize => '11.5' } );
   }

[edit] dump()

[edit] loadFrom()

sub loadFrom(\%source)
Copy each member of \%source hashref as-is into $self, then call analyse(). This is useful for creating an object from a hashref that represents a database row.


[edit] History

Turnip was inspired by the Object class in Java, and by my desire to have common setError() and getConfig() functions available everywhere. The name is inspired by the televised Baldrick's fondness for turnips, and also is a mockery of "Java Bean" - much like Common Lisp Enterprise Eggplants, a project of a friend of this author.

Personal tools