ProgressMonitor::AbstractConfiguration - a base class for all configuration objects


ProgressMonitor documentation Contained in the ProgressMonitor distribution.

Index


Code Index:

NAME

Top

ProgressMonitor::AbstractConfiguration - a base class for all configuration objects

SYNOPSIS

Top

    package SomeClass;

    use classes
    ...

    sub new
    {
        ...
        my $cfg = shift;

        $cfg = ProgressMonitor::AbstractConfiguration::ensureCfgObject($cfg, __PACKAGE__);

        do_something_with($cfg->get_someValue);
        ...
    }

    ...

    ###

    package SomeClassConfiguration;

    use classes
        extends => 'ProgressMonitor::AbstractConfiguration',
        attrs   => ['someValue'],
    ;

    sub defaultAttributeValues
    {
        my $self = shift;

        return {%{$self->SUPER::defaultAttributeValues()}, someValue => 42 };
    }

    sub checkAttributeValues
    {
        my $self = shift;

        $self->SUPER::checkAttributeValues();

        X::Usage->throw("someValue is not a multiple of 42") if $self->get_value % 42;

        return;
    }

DESCRIPTION

Top

This is the base class for configuration data as used by (almost) all classes in this package. The intent is that all 'real' classes have a parallel configuration class where such objects holds the values used to configure the real object.

The main reason for this strategy started out as a way to reuse some of the 'classes' mechanisms for example with automatic getters/setters, but still not expose such methods on the real object. This style also allows a user to create a configuration object and pass it in to several objects - the configuration will be cloned to avoid the user changing values (they may have been used for calculations to set other values - changing them might invalidate such calculations and make things hopelessly confused...).

In practice, creating configuration objects directly is uncommon (?) as the real objects will automatically convert an anonymous hash to an object of the right kind (naming of the class is important - add 'Configuration' to the real class name).

To reuse, you typically only override the defaultAttributeValues and checkAttributeValues methods.

METHODS

Top

new( value1 => data1, value2 => data2, ... )

The constructor for a configuration. Note that this method typically should be treated as 'final' and not be overridden.

Pass in a hash list with the values you want to set. Throws X::UnknownAttr if an unknown attribute is passed or X::Usage if a value is deemed incorrect.

defaultAttributeValues

Takes no arguments, should return a hash reference with results from calling SUPER overlaid with default values for your attributes (and possibly for the SUPER values if desired).

checkAttributeValues

The implementation of this should check that the values for the attributes are 'correct', whatever that entails for your object.

In case of incorrectness, throw X::Usage with a relevant message.

ensureCfgObject( $hashRefOrCfgObject, $packageName)

This is a static helper method typically called from the contructor of the 'real' object and will ensure a hash ref is converted into a configuration object or a configuration object is properly cloned.

TODO

Top

Perhaps this class should provide a simple mechanism for storing/loading data from/to persistence?

AUTHOR

Top

Kenneth Olwing, <knth at cpan.org>

BUGS

Top

I wouldn't be surprised! If you can come up with a minimal test that shows the problem I might be able to take a look. Even better, send me a patch.

Please report any bugs or feature requests to bug-progressmonitor at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=ProgressMonitor. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find general documentation for this module with the perldoc command:

    perldoc ProgressMonitor

ACKNOWLEDGEMENTS

Top

Thanks to my family. I'm deeply grateful for you!

COPYRIGHT & LICENSE

Top


ProgressMonitor documentation Contained in the ProgressMonitor distribution.

package ProgressMonitor::AbstractConfiguration;

use warnings;
use strict;

use Scalar::Util qw(blessed);

# declare the class
#
use classes
  new           => 'new',
  class_methods => ['ensureCfgObject',],
  methods       => ['defaultAttributeValues', 'checkAttributeValues',],
  clone         => 'classes::clone',
  throws        => ['X::Usage',],
  ;

sub new
{
	# get an empty object
	#
	my $self = classes::new_only(shift);

	# initilize it based on the defaults, overlaid with params to us
	#
	classes::init_args($self, %{$self->defaultAttributeValues}, @_);

	# now let the object check that all is ok
	#
	$self->checkAttributeValues;

	return $self;
}

sub defaultAttributeValues
{
	# just return an empty hash
	#
	return {};
}

sub checkAttributeValues
{
	# yep, to us it looks ok! :-)
	#
	return;
}

# class method to help an incoming cfg object to be of the right sort
# as well as cloned if necessary
#
sub ensureCfgObject
{
	my $obj    = shift;
	my $cfgPkg = shift;

	# the cfg package name should always end in this...
	#
	$cfgPkg .= "Configuration";

	if (blessed($obj) && $obj->isa($cfgPkg))
	{
		# clone a passed cfg to ensure it won't change
		#
		return $obj->clone;
	}
	elsif (ref($obj) eq 'HASH' || !defined($obj))
	{
		# get a new cfg, possibly initialized by a hash
		#
		return $cfgPkg->new($obj ? %$obj : ());
	}

	X::Usage->throw("not a hash or $cfgPkg object: $obj");
}

############################

1;    # End of ProgressMonitor::AbstractConfiguration