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.