NAME
OOB - out of bounds data for any data structure in Perl
VERSION
This documentation describes version 0.03.
SYNOPSIS
# object oriented interface
use OOB;
# register attributes
OOB->ContentType;
OOB->EpochStart;
OOB->Currency;
OOB->Accept;
# scalars (or scalar refs)
OOB->ContentType( $message, 'text/html' );
my $type = OOB->ContentType($message);
print <<"MAIL";
Content-Type: $type
$message
MAIL
# arrays
OOB->EpochStart( \@years, 1970 );
my $offset = OOB->EpochStart( \@years );
print $offset + $_ , $/ foreach @years;
# hashes
OOB->Currency( \%salary, 'EUR' );
my $currency = OOB->Currency( \%salary );
print "$_: $salary{$_} $currency\n" foreach sort keys %salary;
# subroutines
OOB->Accept( \&frobnicate, \@classes );
my $classes = OOB->Accept( \&frobnicate );
# functional interface
use OOB qw( OOB_set OOB_get OOB_reset );
package Foo;
OOB_set( $scalar, key => $value );
my $value = OOB_get( @array, 'key' );
OOB_reset( %hash );
package Bar;
my $value = OOB_get( $arrayref, 'key', 'Foo' ); # other module's namespace
DESCRIPTION
This module makes it possible to assign any out of bounds data (attributes) to any Perl data structure with both a functional and an object oriented interface. Out of bounds data is basically represented by a key / value pair.
Object Oriented Interface
The object oriented interface allows you to easily define globally accessible meta-data attributes. To prevent problems by poorly typed attribute names, you need to register a new attribute at least once before being able to set it. Attempting to access any non-existing meta-data attributes will not result in an error, but simply return undef.
Registration of an attribute is simple: just calling it as a class method on the OOB
module is enough:
use OOB;
OOB->ContentType;
After that, you can use that attribute on any Perl data structure:
OOB->ContentType( $string, 'text/html' ); # scalars don't need to be ref'ed
OOB->ContentType( \$string, 'text/html' ); # same as above
OOB->ContentType( \@array, 'text/html' );
OOB->ContentType( \%hash, 'text/html' );
OOB->ContentType( \&sub, 'text/html' );
OOB->ContentType( *FILE, 'text/html' ); # globs
OOB->ContentType( $handle, 'text/html' ); # blessed objects
Functional Interface
The functional interface gives more flexibility but may not be as easy to type. It basically allows you to specify arrays, hashes and subs directly (courtesy of Perl's prototyping feature). The functional interface is in principle limited to the namespace from which it is being called, but can be overridden if necessary.
use OOB qw( OOB_set OOB_get OOB_reset ); # nothing exported by default
package Foo;
OOB_set( $string, ContentType => 'html' );
my $type = OOB_get( $string, 'ContentType' ); # attribute in 'Foo'
package Bar;
my $type = OOB_get( $string, ContentType => 'Foo' ); # other namespace
OOB_set( $string, ContentType => "text/$type" ); # attribute in "Bar"
OOB_set( $string, ContentType => 'text/html' ); # equivalent to object
OOB_set( @array, ContentType => 'text/html' ); # oriented examples, but
OOB_set( %hash, ContentType => 'text/html' ); # limited to the current
OOB_set( &sub, ContentType => 'text/html' ); # namespace
OOB_set( *FILE, ContentType => 'text/html' );
OOB_set( $handle, ContentType => 'text/html' );
THEORY OF OPERATION
The functional interface of the OOB
pragma basically uses the refaddr
of the given value as an internal key to create an "inside-out" hash ref with the given keys and values. If the value is not blessed yet, it will be blessed in the OOB
class, so that it can perform cleanup operations once the value goes out of scope.
If a blessed value is specified, the DESTROY method of the class of the object is stolen, so that OOB
can perform its cleanup after the original DESTROY method was called. This is only supported if the Sub::Identify module is also installed. If that module cannot be found, a warning will be issued once to indicate that no cleanup can be performed for blessed objects, and execution will then continue as normal.
To prevent clashes between different modules use of the out-of-bounds data, the package name of the caller is automatically added to any key specified, thereby giving each package its own namespace in the OOB
environment. However, if need be, a module can access data from another package by the additional specification of its namespace.
The object oriented interface is really nothing more than synctactic sugar on top of the functional interface. The namespace that is being used by all of the attributes specified with the object oriented interface is the OOB
package itself.
REQUIRED MODULES
Scalar::Util (1.14)
AUTHOR
Elizabeth Mattijsen, <liz@dijkmat.nl>.
Please report bugs to <perlbugs@dijkmat.nl>.
ACKNOWLEDGEMENTS
Juerd Waalboer for the insight that you don't need to keep a reference on a blessed Perl data structure such as a scalar, array or hash, but instead can use any reference to that data structure to find out its blessedness.
COPYRIGHT
Copyright (c) 2008 Elizabeth Mattijsen <liz@dijkmat.nl>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.