NAME
Abstract::Meta::Class - Simple meta object protocol implementation.
SYNOPSIS
package
Dummy;
has
'$.attr1'
=> (
default
=> 0);
has
'%.attrs2'
=> (
default
=> {
a
=> 1,
b
=> 3},
item_accessor
=>
'attr2'
);
has
'@.atts3'
=> (
default
=> [1, 2, 3],
required
=> 1,
item_accessor
=>
'attr3'
);
has
'&.att3'
=> (
required
=> 1);
has
'$.att4'
=> (
default
=>
sub
{
'stuff'
} ,
required
=> 1);
my
$dummt
= Dummy->new(
att3
=> 3,
);
use
Dummy;
my
$obj
= Dummy->new(
attr3
=>
sub
{});
my
$attr1
=
$obj
->attr1;
#0
$obj
->set_attr1(1);
$obj
->attr2(
'c'
, 4);
$obj
->attrs2
#{a => 1, b => 3. c => 4};
my
$val_a
=
$obj
->attr2(
'a'
);
my
$item_1
=
$obj
->attr3(1);
$obj
->count_attrs3();
$obj
->push_attrs3(4);
DESCRIPTION
Meta object protocol implementation,
hash/array storage type
To speed up bless time as well optimise memory usage you can use Array storage type. (Hash is the default storage type)
package
Dummy;
storage_type
'Array'
;
has
'$.attr1'
=> (
default
=> 0);
has
'%.attrs2'
=> (
default
=> {
a
=> 1,
b
=> 3},
item_accessor
=>
'attr2'
);
has
'@.attrs3'
=> (
default
=> [1, 2, 3],
required
=> 1,
item_accessor
=>
'attr3'
);
has
'&.attr4'
=> (
required
=> 1);
has
'$.attr5'
;
has
'$.attr6'
=> (
default
=>
sub
{
'stuff'
} ,
required
=> 1);
my
$dummy
= Dummy->new(
attr4
=>
sub
{},
);
use
Data::Dumper;
warn
Dumper
$dummy
;
# bless [0, {a =>1,b => 3}, [1,2,3],sub{},undef,sub {}], 'Dummy'
simple validation and default values
utility methods for an array type
While specyfing array type of attribute
the following methods are added (count ||
push
||
pop
||
shift
||
unshift
)_accessor.
package
Dummy;
has
'@.array'
=> (
item_accessor
=>
'array_item'
);
use
Dummy;
my
$obj
= Dummy->new;
$obj
->count_array();
$obj
->push_array(1);
my
$x
=
$obj
->array_item(0);
my
$y
=
$obj
->pop_array;
#NOTE scalar, array context sensitive
my
$array_ref
=
$obj
->array;
my
@array
=
$obj
->array;
item accessor method for complex types
While specyfing an array or a hash type of attribute then
you may specify item_accessor
for
get/set value by hash key or array
index
.
package
Dummy;
has
'%.hash'
=> (
item_accessor
=>
'hash_item'
);
use
Dummy;
my
$obj
= Dummy->new;
$obj
->hash_item(
'key1'
,
'val1'
);
$obj
->hash_item(
'key2'
,
'val2'
);
my
$val
=
$obj
->hash_item(
'key1'
);
#NOTE scalar, array context sensitive
my
$hash_ref
=
$obj
->hash;
my
%hash
=
$obj
->hash;
perl types validation
associations
This module handles different types of associations(to one, to many, to many ordered).
NOTE: When using the_other_end automatic association/deassociation happens,
celanup method is installed.
package
Class;
has
'$.to_one'
=> (
associated_class
=>
'AssociatedClass'
);
has
'@.ordered'
=> (
associated_class
=>
'AssociatedClass'
);
has
'%.to_many'
=> (
associated_class
=>
'AssociatedClass'
,
item_accessor
=>
'many'
,
index_by
=>
'id'
);
use
Class;
use
AssociatedClass;
my
$obj1
= Class->new(
to_one
=> AssociatedClass->new);
my
$obj2
= Class->new(
ordered
=> [AssociatedClass->new]);
# NOTE: context sensitive (scalar, array)
my
@association_objs
=
$obj2
->ordered;
my
@array_ref
=
$obj2
->ordered;
my
$obj3
= Class->new(
to_many
=> [AssociatedClass->new(
id
=>
'001'
), AssociatedClass->new(
id
=>
'002'
)]);
my
$association_obj
=
$obj3
->many('002);
# NOTE: context sensitive (scalar, array)
my
@association_objs
=
values
%{
$obj3
->to_many};
my
$hash_ref
=
$obj3
->to_many;
- bidirectional associations (the_other_end attribute)
package
Master;
has
'$.name'
;
has
'%.details'
=> (
associated_class
=>
'Detail'
,
the_other_end
=>
'master'
,
item_accessor
=>
'detail'
,
index_by
=>
'id'
);
package
Detail;
has
'$.id'
=> (
required
=> 1);
has
'$.master'
=> (
associated_class
=>
'Master'
,
the_other_end
=>
'details'
);
use
Master;
use
Detail;
my
@details
= (
Detail->new(
id
=> 1),
Detail->new(
id
=> 2),
Detail->new(
id
=> 3),
);
my
$master
= Master->new(
name
=>
'foo'
,
details
=> [
@details
]);
$details
[0]->master->name;
-
while
using an array/hash association storage remove_<attribute_name> | add_<attribute_name> are added.
$master
->add_details(Detail->new(
id
=> 4),);
$master
->remove_details(
$details
[0]);
#cleanup method is added to class, that deassociates all bidirectional associations
decorators
....- on_validate
- on_change
- on_read
- initialise_method
package
Triggers;
has
'@.y'
=> (
on_change
=>
sub
{
my
(
$self
,
$attribute_name
,
$scope
,
$value_ref
,
$index
) =
@_
;
# scope -> mutator, item_accessor
...
do
some stuff
# process further in standard way by returning true
$self
;
},
# replaces standard read
on_read
=>
sub
{
my
(
$self
,
$attr_name
,
$scope
,
$index
)
#scope can be: item_accessor, accessor
...
#return requested value
},
item_accessor
=>
'y_item'
);
use
Triggers;
my
$obj
= Triggers->new(
y
=> [1,2,3]);
- add hoc decorators
package
Class;
has
'%.attrs'
=> (
item_accessor
=>
'attr'
);
my
$attr
= DynamicInterceptor->meta->attribute(
'attrs'
);
my
$obj
= DynamicInterceptor->new(
attrs
=> {
a
=> 1,
b
=> 2});
my
$a
=
$obj
->attr(
'a'
);
my
%hook_access_log
;
my
$ncode_ref
=
sub
{
my
(
$self
,
$attribute
,
$scope
,
$key
) =
@_
;
#do some stuff
# or
if
(
$scope
eq
'accessor'
) {
return
$values
;
}
else
{
return
$values
->{
$key
};
}
};
$attr
->set_on_read(
$ncode_ref
);
# from now it will apply to Class::attrs calls.
my
$a
=
$obj
->attr(
'a'
);
abstract methods/classes
package
BaseClass;
has
'$.attr1'
;
abstract
=>
'method1'
;
package
Class;
sub
method1 {};
use
Class;
my
$obj
= BaseClass->new;
# abstract classes
package
InterfaceA;
abstract_class;
abstract
=>
'method1'
;
abstract
=>
'method2'
;
package
ClassA;
sub
method1 {};
sub
method2 {};
use
Class;
my
$classA
= Class->new;
package
Class;
has
'attr1'
;
has
'interface_attr'
=> (
associated_class
=>
'InterfaceA'
,
required
=> 1);
use
Class;
my
$obj
= Class->new(
interface_attr
=>
$classA
);
external attributes storage
You may want store attributes
values
outside the blessed reference, then you may
use
transistent keyword (Inside Out Objects)
package
Transistent;
has
'$.attr1'
;
has
'$.x'
=> (
required
=> 1);
has
'$.t'
=> (
transistent
=> 1);
has
'%.th'
=> (
transistent
=> 1);
has
'@.ta'
=> (
transistent
=> 1);
use
Transistent;
my
$obj
= Transistent->new(
attr1
=> 1,
x
=> 2,
t
=> 3,
th
=> {
a
=>1},
ta
=> [1,2,3]);
use
Data::Dumper;
Dumper
$obj
;
Cleanup and DESTORY methods are added to class, that
delete
externally stored attributes.
METHODS
- new
- install_cleanup
-
Install cleanup method
- install_destructor
-
Install destructor method
- install_constructor
-
Install constructor
- apply_contructor_parameters
-
Applies constructor parameters.
- meta
- attributes
-
Returns attributes for meta class
- set_attributes
-
Mutator sets attributes for the meta class
- has_cleanup_method
-
Returns true if cleanup method was generated
- set_cleanup_method
-
Sets clean up
- has_destory_method
-
Returns true is destroy method was generated
- set_destroy_method
-
Sets set_destructor flag.
- initialise_method
-
Returns initialise method's name default is 'initialise'
- is_abstract
-
Returns is class is an abstract class.
- set_abstract
-
Set an abstract class flag.
- set_initialise_method
-
Mutator sets initialise_method for the meta class
- associated_class
-
Returns associated class name
- set_associated_class
-
Mutator sets associated class name
- all_attributes
-
Returns all_attributes for all inherited meta classes
- attribute
-
Returns attribute object
- super_classes
- install_meta_class
-
Adds class to meta repository.
- meta_class
-
Returns meta class object for passed in class name.
- add_attribute
- attribute_class
-
Returns meta attribute class
- has
-
Creates a meta attribute.
Takes attribute name, and the following attribute options: see also Abstract::Meta::Attribute
- storage_type
-
Sets storage type for the attributes. allowed values are Array/Hash
- abstract
-
Creates an abstract method
- abstract_class
-
Creates an abstract method
- install_abstract_methods
- install_attribute_methods
-
Installs attribute methods.
- add_method
-
Adds code reference to the class symbol table. Takes a class name, method name and CODE reference.
- remove_method
-
Adds code reference to the class symbol table. Takes a class name, method name and CODE reference.
- constructor_attributes
-
Returns a list of attributes that need be validated and all that have default value
SEE ALSO
COPYRIGHT AND LICENSE
The Abstract::Meta::Class module is free software. You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.
AUTHOR
Adrian Witas, adrian@webapp.strefa.pl