NAME
Class::MakeMethods::Composite::Universal - Composite Method Tricks
SYNOPSIS
package MyClass;
use Class::MakeMethods::Composite::Universal (
hook => 'init',
);
sub new {
my $package = shift;
my $self = bless {}, $package;
$self->init();
return $self;
}
MyClass->
package MySubClass;
@ISA = 'MyClass';
...
MyClass->foo( 'Foozle' );
print MyClass->foo();
MyClass->my_list(0 => 'Foozle', 1 => 'Bang!');
print MyClass->my_list(1);
MyClass->my_index('broccoli' => 'Blah!', 'foo' => 'Fiddle');
print MyClass->my_index('foo');
...
my $obj = MyClass->new(...);
print $obj->foo(); # all instances default to same value
$obj->foo( 'Foible' ); # until you set a value for an instance
print $obj->foo(); # it now has its own value
print MySubClass->foo(); # intially same as superclass
MySubClass->foo('Foobar'); # but overridable per subclass
print $subclass_obj->foo(); # and shared by its instances
$subclass_obj->foo('Fosil');# until you override them...
DESCRIPTION
The Composite::Universal suclass of MakeMethods provides some generally-applicable types of methods based on Class::MakeMethods::Composite.
METHOD GENERATOR TYPES
patch
The patch ruleset generates composites whose core behavior is based on an existing subroutine.
Here's an sample usage:
sub foo {
my $count = shift;
return 'foo' x $count;
}
Class::MakeMethods::Composite::Universal->make(
-ForceInstall => 1,
patch => {
name => 'foo',
pre_rules => [
sub {
my $method = pop @_;
if ( ! scalar @_ ) {
@{ $method->{args} } = ( 2 );
}
},
sub {
my $method = pop @_;
my $count = shift;
if ( $count > 99 ) {
Carp::confess "Won't foo '$count' -- that's too many!"
}
},
],
post_rules => [
sub {
my $method = pop @_;
if ( ref $method->{result} eq 'SCALAR' ) {
${ $method->{result} } =~ s/oof/oozle-f/g;
} elsif ( ref $method->{result} eq 'ARRAY' ) {
map { s/oof/oozle-f/g } @{ $method->{result} };
}
}
],
},
);
make_patch
A convenient wrapper for make()
and the patch
method generator.
Provides the '-ForceInstall' flag, which is required to ensure that the patched subroutine replaces the original.
For example, one could add logging to an existing method as follows:
Class::MakeMethods::Composite::Universal->make_patch(
-TargetClass => 'SomeClassOverYonder',
name => 'foo',
pre_rules => [
sub { my $method = pop; warn "Arguments:", @_ }
]
post_rules => [
sub { my $method = pop; warn "Result:", $method->{result} }
]
);
hook
External interface is normal; internally calls array of fragments. Among other things, this should allow meta-methods to individually provide "on init" or "on destroy" code.
How do you add to the hook? Pre/post, or arbitrary order? Ability to remove/replace specifc ones? Assign name? Loop in name order?
package MyWidget;
use C::MM::Composite (
hook => 'init',
);
sub new {
my $widget = ...;
$widget->init();
return $widget;
}
MyWidget->_hook_method('init',
'post+' => sub { (shift)->{count} ||= 3 },
);
NOTE: THIS METHOD GENERATOR IS INCOMPLETE.
The _hook_method interface, or an improvement thereto, needs to be added.
Hook methods should call up the inheritance tree.
SEE ALSO
See Class::MakeMethods and Class::MakeMethods::Composite for an overview of the method-generation framework this is based on.
See Class::MakeMethods::Guide for a getting-started guide, annotated examples of usage, and a listing of the method generation classes included in this distribution.
See Class::MakeMethods::ReadMe for distribution, installation, version and support information.