OOP::Perlish::Class::Abstract
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)
package MyAbstractClass; use base qw(OOP::Perlish::Class::Abstract); BEGIN { __PACKAGE__->_interfaces( my_interface => 'required', my_optional_interface => 'optional', my_optional_but_true => 'optional_true', ); };
package MyImplementationClass; use base qw(MyAbstractClass); sub my_interface { my ($self) = @_; return 'foo'; }
package MyConsumerClass; use base qw(OOP::Perlish::Class); BEGIN { __PACKAGE__->_accessors( foo => { type => 'OBJECT', implements => [ 'MyAbstractClass' ], }, ); }; sub quux { my ($self) = @_; return $self->foo()->my_interface(); }
my $foo = MyImplementationClass->new(); my $bar = MyConsumerClass->new( foo => $foo ); print $bar->quux() . $/;
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.:
____oop_perlish_class_interface_impl_
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.
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;
To install OOP::Perlish::Class, copy and paste the appropriate command in to your terminal.
cpanm
cpanm OOP::Perlish::Class
CPAN shell
perl -MCPAN -e shell install OOP::Perlish::Class
For more information on module installation, please visit the detailed CPAN module installation guide.