The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

XML::Schema::Base - base class for various XML::Schema::* modules

SYNOPSIS

    package XML::Schema::MyModule;

    use base qw( XML::Schema::Base );
    use vars qw( $ERROR @MANDATORY %OPTIONAL );

    @MANDATORY = qw( id );
    %OPTIONAL  =   ( msg => 'Hello World' );

    sub init {
        my ($self, $config) = @_;

        # search inheritance tree for mandatory/optional params
        my $baseargs = $self->_baseargs(qw( @MANDATORY %OPTIONAL ));
        my ($mandatory, $optional) = @$baseargs;

        # set all mandatory parameters from $config
        $self->_mandatory($mandatory, $config)
            || return;

        # set optional params from $config or use defaults
        $self->_optional($optional, $config)
            || return;

        return $self;
    }

    package main;

    my $module = XML::Schema::MyModule->new( id => 12345 )
         || die $XML::Schema::MyModule::ERROR;

DESCRIPTION

This module implements a simple base class from which numerous other XML::Schema::* modules are derived.

PUBLIC METHODS

new(@config)

General purpose constructor method which can be used to instantiate new objects of classes derived from XML::Schema::Base.

The method expects a hash array of configuration items either passed directly by reference or as list of key => value pairs which are automatically folded into a hash reference. A new object is constructed from a blessed hash and the init() method is called, passing the configuration hash as an argument.

    package XML::Schema::MyModule;

    use base qw( XML::Schema::Base );
    use vars qw( $ERROR );

    package main;

    my $obj1 = XML::Schema::MyModule->new({ pi => 3.14, e => 2.718 });
    my $obj2 = XML::Schema::MyModule->new(  pi => 3.14, e => 2.718  );

init(\%config)

Called by the new() constructor to perform any per-object initialisation. A reference to a hash array of configuration parameters is passed as an argument. The method should return $self on success or undef on failure (e.g. by calling $self->error()).

    sub init {
        my ($self, $config) = @_;
        
        $self->{ _LIKES } = $config->{ likes }
            || return $self->error("no 'likes' parameter specified") 

        return $self;
    }

error($msg)

Can be called as a class or object method to get or set the relevant error variable. Returns the current value of the error variables when called without arguments, or undef when called with argument(s) which are used to set the error variable (multiple arguments are concatenated).

    # class method to set $XML::Schema::MyModule::ERROR
    XML::Schema::MyModule->error('Failed to have cake and eat it');

    # class method to retrieve $XML::Schema::MyModule::ERROR
    warn XML::Schema::MyModule->error();

    # object method to set $myobj->{ _ERROR }
    $myobj->error('Stone throwing detected in glass house');

    # object method to get $myobj->{ _ERROR }
    warn $myobj->error();

throw($error)

Called to throw an error as an XML::Schema::Exception object using the error message passed as the first argument as the information field for the exception. The error type is defined in the $ETYPE package variable in the derived class or defaults to the value of $ETYPE in this base class package (the string 'undef', by default).

    package XML::Schema::MyModule;

    use base qw( XML::Schema::Base );
    use vars qw( $ETYPE );
    $ETYPE = 'MyModule';

    package main;

    $myobj = XML::Schema::MyModule->new();
    $myobj->throw('An error');      # throws "[MyModule] An error"

Alternately, the method can be called with two explicit arguments to denote the type and info fields.

    $myobj->throw('Cake', 'Let them eat it!');
                                    # throws "[Cake] Let them eat it!"

PRIVATE METHODS

These methods are deemed "private" (or more accurately, "protected") and are intended for the use of classes derived from XML::Schema::Base.

_baseargs(@names)

This method walks up the inheritance tree collecting various package variables along the way and collating them for the derived object class. Variable names in which the caller is interested should be passed as arguments. A reference to a list is returned which contains further references to lists and/or hash arrays, depending on the variable type.

    sub init {
        my ($self, $config) = @_;

        my $baseargs = $self->_baseargs(qw( @MANDATORY %OPTIONAL ));
        my ($mandatory, $optional) = @$baseargs;

        ...

        return $self;
    }

For example, consider the following inheritance tree:

    package XML::Schema::Test::Foo;
    use base qw( XML::Schema::Base );
    use vars qw( @MANDATORY %OPTIONAL );

    @MANDATORY = qw( one two );
    %OPTIONAL  = ( foo => 'default foo' );

    package XML::Schema::Test::Bar;
    use base qw( XML::Schema::Base );
    use vars qw( @MANDATORY %OPTIONAL );

    @MANDATORY = qw( three four );
    %OPTIONAL  = ( bar => 'default bar' );

    package XML::Schema::Test::Baz;
    use base qw( XML::Schema::Test::Foo
                 XML::Schema::Test::Bar );
    use vars qw( @MANDATORY %OPTIONAL );

    @MANDATORY = qw( five six );
    %OPTIONAL  = ( baz => 'default baz' );

Now let's call the _baseargs() method against these different packages and see what they return.

    my @names = qw( @MANDATORY %OPTIONAL );

    XML::Schema::Test::Foo->_baseargs(@names);

    # returns:
    # [ 
    #     [ 'one', 'two' ] 
    #     { foo => 'default foo' }
    # ]

    XML::Schema::Test::Bar->_baseargs(@names);

    # returns:
    # [ 
    #     [ 'three', 'four' ] 
    #     { bar => 'default bar' }
    # ]

    XML::Schema::Test::Baz->_baseargs(@names);

    # returns:
    # [ 
    #     [ 'one', 'two', 'three', 'four' ] 
    #     { foo => 'default foo'
    #       bar => 'default bar'
    #       baz => 'default baz' 
    #     }
    # ]

Note that package variables specified as hash arrays can also be specified as lists. In this case, the list is assumed to represent the hash keys which all have empty (but defined) values.

    @OPTIONAL = qw( foo bar );

    # equivalent to:
    %OPTIONAL = ( foo => '', bar => '' );

_mandatory(\@names, \%config)

This method examines the $config hash array for values specified by name in the $names list and copies them to the $self object. All items are deemed mandatory and the method will raise an error and return undef if any item is not defined.

    sub init {
        my ($self, $config) = @_;

        my $baseargs = $self->_baseargs(qw( @MANDATORY ));

        return $self->_mandatory($baseargs->[0], $config);
    }

_optional(\%names, \%config)

Like _mandatory, this method examines the $config hash array for values specified as keys in the $names hash and copies them to the $self object. The values in the $names hash are used as defaults for items which are not defined in $config. If the default value contains a CODE reference then the subroutine will be called. The $names item may also be specified as a reference to a list in which case all default values are set to the empty string, ''.

    sub init {
        my ($self, $config) = @_;

        my $baseargs = $self->_baseargs(qw( %OPTIONAL ));

        return $self->_optional($baseargs->[0], $config);
    }

_arguments(\@names, \@args)

Similar to _mandatory() and _optional() above, this method sets named values but in this case from positional arguments. The expected names of values are specified by reference to a list as the first argument and the list of candidate values is passed by reference as the second. An error is raised and undef returned if any value is undefined.

    sub new {
        my ($class, @args) = @_;

        my $baseargs = $class->_baseargs('@ARGUMENTS');

        my $self = bless {
            _ERROR  => '',
        }, $class;

        return $self->_arguments($baseargs->[0], \@args)
            || $class->error($self->error());
    }

AUTHOR

Andy Wardley <abw@kfs.org>

VERSION

This is version $Revision: 1.2 $ of the XML::Schema::Base module, distributed with version 0.1 of the XML::Schema module set.

COPYRIGHT

Copyright (C) 2001 Canon Research Centre Europe Ltd. All Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

See XML::Schema for general information about these modules and their use.