NAME
OOP::Perlish::Class::Abstract
DESCRIPTION
Quickly and easily create abstract classes, which can easily be tested for via 'isa' or OOP::Perlish::Class::Accessor->implements( [ 'ClassA', 'ClassB' ] ); ('implements' is a polymorphism test, not an inheritance test, and is generally preferred)
SYNOPSIS
- Defining an abstract class
-
package
MyAbstractClass;
BEGIN {
__PACKAGE__->_interfaces(
my_interface
=>
'required'
,
my_optional_interface
=>
'optional'
,
my_optional_but_true
=>
'optional_true'
,
);
};
- Later in an implementation class:
-
- Meanwhile, in a consuming class
-
package
MyConsumerClass;
BEGIN {
__PACKAGE__->_accessors(
foo
=> {
type
=>
'OBJECT'
,
implements
=> [
'MyAbstractClass'
],
},
);
};
sub
quux
{
my
(
$self
) =
@_
;
return
$self
->foo()->my_interface();
}
- And finally, when used:
-
my
$foo
= MyImplementationClass->new();
my
$bar
= MyConsumerClass->new(
foo
=>
$foo
);
print
$bar
->quux() . $/;
USAGE
The module provides handlers for 'required', 'optional', and 'optional_true' types of interface definitions via the following built-in method factories:
############################################################################################
## Return a subroutine for the required interfaces
############################################################################################
sub
____oop_perlish_class_interface_impl_required
{
my
(
$self
,
$name
) =
@_
;
my
$class
=
ref
(
$self
) ||
$self
;
$self
->____OOP_PERLISH_CLASS_REQUIRED_INTERFACES()->{
$name
} = 1;
return
sub
{ confess(
"Interface $name is required, but was not defined in $class (nor in the ancestory of $class)"
); };
}
############################################################################################
## Return a subroutine for the optional (false) interfaces
############################################################################################
sub
____oop_perlish_class_interface_impl_optional
{
my
(
$self
,
$name
) =
@_
;
return
sub
{
return
; };
}
############################################################################################
## Return a subroutine for optional_true interfaces
############################################################################################
sub
____oop_perlish_class_interface_impl_optional_true
{
my
(
$self
,
$name
) =
@_
;
return
sub
{
return
1; };
}
if you wish to add additional handlers for an abstract class; simply define a method with the type prefixed with ____oop_perlish_class_interface_impl_
e.g.:
sub
____oop_perlish_class_interface_impl_my_type
{
return
sub
{
return
'default sub for my_type'
; };
}
Which would allow you to specify in the _interfaces() call
BEGIN {
__PACKAGE__->_interfaces(
my_interface
=>
'my_type'
,
);
};
This is mostly useful for specifying default interfaces that are expected to return references to (possibly empty) hashes or arrays.
DIAGNOSTICS
invokes confess() whenever a method is called that was
'required'
but never
defined
.
invokes confess() whenever a type is specified in __PACKAGE__->_interfaces() that does not have a handler
defined
.
invokes confess() whenever an object is instantiated via new and is missing a required interface definition;