1package Class::Delegation;
2
3our $VERSION = '1.9.0';
4
5use strict;
6use Carp;
7
8sub ::DEBUG { 0 };
9
10my %mappings;
11
12sub import {
13	my $class = shift;
14	my $caller = caller();
15	while (@_) {
16		push @{$mappings{$caller}}, Class::Delegation::->_new(\@_);
17	}
18}
19
20INIT {
21	foreach my $class (keys %mappings) {
22		_install_delegation_for($class);
23	}
24}
25
26sub _install_delegation_for {
27	use vars '$AUTOLOAD';
28	no strict 'refs';
29	my ($class) = @_;
30	my $symbol = "${class}::AUTOLOAD";
31	print STDERR "Installing $symbol\n" if ::DEBUG;
32	my $real_AUTOLOAD = *{$symbol}{CODE}
33			 || sub {croak "Could not delegate $AUTOLOAD"};
34
35	local $SIG{__WARN__} = sub {};
36	*$symbol = sub {
37		$$symbol = $AUTOLOAD;
38		my ($class, $method) = $AUTOLOAD =~ m/(.*::)(.*)/;
39		my ($invocant, @args) = @_;
40		print STDERR "Delegating: $AUTOLOAD...\n" if ::DEBUG;
41		use Data::Dumper 'Dumper';
42		print STDERR "...on: ", Dumper $invocant if ::DEBUG;
43		my @context = ($invocant, $method, @args);
44		$invocant = "${class}${invocant}" unless ref $invocant;
45		my $wantarray = wantarray;
46		my @delegators = _delegators_for(@context);
47		goto &{$real_AUTOLOAD} unless @delegators;
48		my (@results, $delegated);
49		DELEGATOR: foreach my $delegator ( @delegators ) {
50			next if $delegator->{other} && keys %$delegated;
51			my @to = @{$delegator->{to}};
52			my @as = @{$delegator->{as}};
53			if (@to==1) {
54				print STDERR "[$to[0]]\n" if ::DEBUG;
55				next DELEGATOR if exists $delegated->{$to[0]};
56				foreach my $as (@as) {
57					push @results, delegate($delegated,$wantarray,$invocant,$to[0],$as,\@args);
58				}
59			}
60			elsif (@as==1) {
61				print STDERR "[$to[0]]\n" if ::DEBUG;
62				foreach my $to (@to) {
63					next if exists $delegated->{$to};
64					push @results, delegate($delegated,$wantarray,$invocant,$to,$as[0],\@args);
65				}
66			}
67			else {
68				while (1) {
69					last unless @to && @as;
70					my $to = shift @to;
71					my $as = shift @as;
72					next if exists $delegated->{$to};
73					push @results, delegate($delegated,$wantarray,$invocant,$to,$as,\@args);
74				}
75			}
76		}
77		goto &{$real_AUTOLOAD} unless keys %$delegated;
78		return $wantarray
79			? ( @results>1 ? @results : @{$results[0]} )
80			: ( @results>1 ? \@results : $results[0] );
81	};
82
83	unless (*{"${class}::DESTROY"}{CODE} ||
84		_delegators_for($class,'DESTROY')) {
85		*{"${class}::DESTROY"} = sub {};
86	}
87}
88
89sub delegate {
90	my ($delegated,$wantarray,$invocant,$to,$as,$args) = @_;
91	no strict 'refs';
92	my $target = ref $to            ? $to
93		   : $to =~ /^->(\w+)$/ ? $invocant->$+()
94		   : $to eq -SELF       ? $invocant
95		   :                      $invocant->{$to};
96	return unless eval {
97		$target->can($as)  || $target->can('AUTOLOAD')
98	};
99	my $result = $wantarray
100			? [$target->$as(@$args)]
101			: $target->$as(@$args);
102	return if $@;
103	$_[0]->{$to}++;
104	return $result
105}
106
107sub _delegators_for {
108	my ($self, $method, @args) = @_;
109
110	my @attrs;
111	my $class = ref($self)||$self;
112	foreach my $candidate ( @{$mappings{$class}} ) {
113		push @attrs, $candidate->{send}->can_send(scalar(@attrs),
114							  $candidate->{to},
115							  $candidate->{as},
116							  @_);
117	}
118	return @attrs if @attrs;
119        no strict 'refs';
120	my @ancestors = @{$class.'::ISA'};
121	my $parent;
122	while ($parent = shift @ancestors) {
123	    next unless exists $mappings{$parent};
124	    foreach my $candidate ( @{$mappings{$parent}} ) {
125		push @attrs, $candidate->{send}->can_send(scalar(@attrs),
126							  $candidate->{to},
127							  $candidate->{as},
128							  @_);
129	    }
130	    return @attrs if @attrs;
131	    unshift @ancestors, @{$parent.'::ISA'};
132	}
133	return @attrs;
134}
135
136sub _new {
137	my ($class, $args) = @_;
138	my ($send, $send_val) = splice @$args, 0, 2;
139	croak "Expected 'send => <method spec>' but found '$send => $send_val'"
140		unless $send eq 'send';
141	croak "The expected 'to => <attribute spec>' is missing at end of list"
142		unless @$args >= 2;
143	my ($to, $to_val) = splice @$args, 0, 2;
144	croak "Expected 'to => <attribute spec>' but found '$to => $to_val'"
145		unless $to eq 'to';
146
147	$send_val  = _class_for(Send => $send_val)->_new($send_val);
148	my $to_obj = _class_for(To => $to_val)->_new($to_val);
149	my $self = bless { send=>$send_val, to=>$to_obj }, $class;
150	if (($args->[0]||"") eq 'as') {
151		my ($as, $as_val) = splice @$args, 0, 2;
152		croak "Arrays specified for 'to' and 'as' must be same length"
153			unless ref($to_val) ne 'ARRAY'
154			    || ref($as_val) ne 'ARRAY'
155			    || @$to_val == @$as_val;
156		$self->{as} = _class_for(As => $as_val)->_new($as_val);
157	}
158	else {
159		croak "'to => -SELF' is meaningless without 'as => <new_name>'"
160			if $to_val eq -SELF;
161		$self->{as} = Class::Delegation::As::Sent->_new();
162	}
163	return $self;
164}
165
166my %allowed;
167@{$allowed{Send}}{qw(ARRAY Regexp CODE)} = ();
168@{$allowed{To}}{qw(ARRAY Regexp CODE)} = ();
169@{$allowed{As}}{qw(ARRAY CODE)} = ();
170
171sub _class_for {
172	my ($subclass, $value) = @_;
173	my $type = ref($value);
174	return "Class::Delegation::${subclass}::SCALAR" unless $type;
175	croak "'\l$subclass' value cannot be $type reference"
176		unless exists $allowed{$subclass}{$type};
177	return "Class::Delegation::${subclass}::${type}";
178}
179
180package # Hide from CPAN indexer
181SELF;
182
183sub DESTROY {}
184sub AUTOLOAD {
185	my ($name) = $SELF::AUTOLOAD =~ m/.*::(.+)/;
186	bless \$name, 'SELF'
187}
188use overload 'neg' => sub { "->${$_[0]}" };
189
190
191package Class::Delegation::Send::SCALAR;
192
193sub _new {
194	return bless {}, "Class::Delegation::Send::ALL" if $_[1] eq '-ALL';
195	return bless {}, "Class::Delegation::Send::OTHER" if $_[-1] eq '-OTHER';
196	my $val = pop;
197	return bless \$val, $_[0]
198}
199
200sub can_send {
201	my ($self, $sent, $to, $as, @context) = @_;
202	return { to => [$to->attr_for(@context)],
203		 as => [$as->name_for(@context)],
204	       }
205		if $$self eq $context[1];
206	return;
207}
208
209
210package Class::Delegation::Send::ARRAY;
211
212sub _new {
213	my @delegators =
214	    map { Class::Delegation::_class_for(Send => $_)->_new($_) } @{$_[1]};
215	bless \@delegators, $_[0];
216}
217
218sub can_send {
219	my ($self, @context) = @_;
220	return map { $_->can_send(@context) } @$self;
221}
222
223
224package Class::Delegation::Send::Regexp;
225
226sub _new {
227	my ($class, $regex) = @_;
228	my $self = bless \$regex, $class;
229	return $self;
230}
231
232
233sub can_send {
234	my ($self, $sent, $to, $as, @context) = @_;
235	return { to => [$to->attr_for(@context)],
236		 as => [$as->name_for(@context)],
237	       }
238		if $context[1] =~ $$self;
239	return;
240}
241
242
243package Class::Delegation::Send::CODE;
244
245sub _new { bless $_[1], $_[0] }
246
247sub can_send {
248	my ($self, $sent, $to, $as, @context) = @_;
249	return { to => [$to->attr_for(@context)],
250		 as => [$as->name_for(@context)],
251	       }
252		if $self->(@context);
253	return;
254}
255
256package Class::Delegation::Send::ALL;
257
258sub can_send {
259	my ($self, $sent, $to, $as, @context) = @_;
260	return { to => [$to->attr_for(@context)],
261		 as => [$as->name_for(@context)],
262	       }
263		if $context[1] ne 'DESTROY';
264	return;
265}
266
267package Class::Delegation::Send::OTHER;
268
269sub can_send {
270	my ($self, $sent, $to, $as, @context) = @_;
271	return { to => [$to->attr_for(@context)],
272		 as => [$as->name_for(@context)],
273		 other => 1,
274	       }
275		if $context[1] ne 'DESTROY';
276	return;
277}
278
279
280package Class::Delegation::To::SCALAR;
281
282sub _new {
283	my ($class, $value) = @_;
284	return bless {}, "Class::Delegation::To::ALL" if $value eq '-ALL';
285	return bless \$value, $class
286}
287
288sub attr_for { return ${$_[0]} }
289
290
291package Class::Delegation::To::ARRAY;
292
293sub _new {
294	my ($class, $array) = @_;
295	bless [ map {("Class::Delegation::To::".(ref||"SCALAR"))->_new($_)} @$array ], $class;
296}
297
298sub attr_for {
299	my ($self, @context) = @_;
300	return map { $_->attr_for(@context) } @$self;
301}
302
303package Class::Delegation::To::Regexp;
304
305sub _new {
306	my ($class, $regex) = @_;
307	my $self = bless \$regex, $class;
308	return $self;
309}
310
311sub attr_for {
312	my ($self, $invocant, @context) = @_;
313	print STDERR "[[$$self]]\n" if ::DEBUG;
314	return grep {  $_ =~ $$self } keys %$invocant;
315}
316
317
318package Class::Delegation::To::CODE;
319
320sub _new { bless $_[1], $_[0] }
321
322sub attr_for {
323	my ($self, @context) = @_;
324	return $self->(@context)
325}
326
327
328package Class::Delegation::To::ALL;
329
330sub attr_for {
331	my ($self, $invocant, @context) = @_;
332	return keys %$invocant;
333}
334
335
336
337package Class::Delegation::As::SCALAR;
338
339sub _new {
340	my ($class, $value) = @_;
341	bless \$value, $class;
342}
343
344sub name_for { ${$_[0]} }
345
346package Class::Delegation::As::ARRAY;
347
348sub _new {
349	my ($class, $value) = @_;
350	bless $value, $class;
351}
352
353sub name_for { @{$_[0]} }
354
355
356package Class::Delegation::As::Sent;
357
358sub _new { bless {}, $_[0] }
359
360sub name_for {
361	my ($self, $invocant, $method) = @_;
362	return $method;
363}
364
365package Class::Delegation::As::CODE;
366
367sub _new { bless $_[1], $_[0] }
368
369sub name_for {
370	my ($self, @context) = @_;
371	return $self->(@context)
372}
373
3741;
375
376__END__
377
378=head1 NAME
379
380Class::Delegation - Object-oriented delegation
381
382=head1 VERSION
383
384This document describes version 1.9.0 of Class::Delegation
385released April 23, 2002.
386
387=head1 SYNOPSIS
388
389        package Car;
390
391        use Class::Delegation
392                send => 'steer',
393                  to => ["left_front_wheel", "right_front_wheel"],
394
395                send => 'drive',
396                  to => ["right_rear_wheel", "left_rear_wheel"],
397		  as => ["rotate_clockwise", "rotate_anticlockwise"]
398
399                send => 'power',
400                  to => 'flywheel',
401                  as => 'brake',
402
403                send => 'brake',
404                  to => qr/.*_wheel$/,
405
406		send => 'halt'
407		  to => -SELF,
408		  as => 'brake',
409
410                send => qr/^MP_(.+)/,
411                  to => 'mp3',
412                  as => sub { $1 },
413
414                send => -OTHER,
415                  to => 'mp3',
416
417                send => 'debug',
418                  to => -ALL,
419                  as => 'dump',
420
421                send => -ALL,
422                  to => 'logger',
423                ;
424
425
426=head1 BACKGROUND
427
428[Skip to L<"DESCRIPTION"> if you don't care why this module exists]
429
430Inheritance is one of the foundations of object-oriented programming. But
431inheritance has a fundamental limitation: a class can only directly inherit
432once from a given parent class. This limitation occasionally
433leads to awkward work-arounds like this:
434
435	package Left_Front_Wheel;   use base qw( Wheel );
436	package Left_Rear_Wheel;    use base qw( Wheel );
437	package Right_Front_Wheel;  use base qw( Wheel );
438	package Right_Rear_Wheel;   use base qw( Wheel );
439
440	package Car;                use base qw(Left_Front_Wheel
441						Left_Rear_Wheel
442						Right_Front_Wheel
443						Right_Rear_Wheel);
444
445Worse still, the method dispatch semantics of most languages (including Perl)
446require that only a single inherited method (in Perl, the one that is
447left-most-depth-first in the inheritance tree) can handle a particular
448method invocation. So if the Wheel class provides methods to steer a
449wheel, drive a wheel, or stop a wheel, then calls such as:
450
451        $car->steer('left');
452        $car->drive(+55);
453        $car->brake('hard');
454
455will only be processed by the left front wheel.  This will probably not
456produce desirable road behaviour.
457
458It is often argued that it is simply a synecdochic mistake to treat a
459car as a specialized form of four wheels, but this argument is
460I<far> from conclusive. And, regardless of its philosophical merits, programmers often do conceptualize
461composite systems in exactly this way.
462
463The alternative is, of course, to make the four wheels I<attributes> of the
464class, rather than I<ancestors>:
465
466        package Car;
467
468        sub new {
469                bless { left_front_wheel  => Wheel->new('steer', 'brake'),
470                        left_rear_wheel   => Wheel->new('drive', 'brake'),
471                        right_front_wheel => Wheel->new('steer', 'brake'),
472                        right_rear_wheel  => Wheel->new('drive', 'brake'),
473                      }, $_[0];
474        }
475
476Indeed some object-oriented languages (e.g. Self) do away with
477inheritance entirely and rely exclusively on the use of attributes to
478implement class hierarchies.
479
480
481=head2 The problem(s) with attribute-based hierarchies
482
483Using attributes instead of inheritance does solve the problem:
484it allows a Car to directly have four wheels. However, this solution
485creates a new problem: it requires that the class manually redispatch (or
486I<delegate>) every method call:
487
488        sub steer {
489                my $self = shift;
490                return ( $self->{left_front_wheel}->steer(@_),
491                         $self->{right_front_wheel}->steer(@_), );
492        }
493
494        sub drive {
495                my $self = shift;
496                return ( $self->{left_rear_wheel}->drive(@_),
497                         $self->{right_rear_wheel}->drive(@_),  );
498        }
499
500        sub brake {
501                my $self = shift;
502                return ( $self->{left_front_wheel}->brake(@_),
503                         $self->{left_rear_wheel}->brake(@_),
504                         $self->{right_front_wheel}->brake(@_),
505                         $self->{right_rear_wheel}->brake(@_),  );
506        }
507
508
509C<AUTOLOAD> methods can help in this regard, but usually at the cost of
510readability and maintainability:
511
512        sub AUTOLOAD {
513                my $self = shift;
514                $AUTOLOAD =~ s/.*:://;
515                my @results;
516                return map { $self->{$_}->$AUTOLOAD(@_) },
517                        grep { $self->{$_}->can($AUTOLOAD) },
518                         keys %$self;
519        }
520
521Often, the simple auto-delegation mechanism shown above cannot
522be used at all, and the various cases must be hand-coded into the C<AUTOLOAD>
523or into separate named methods (as shown earlier).
524
525For example, an electric car might also have a flywheel and an MP3 player:
526
527        sub new {
528                bless { left_front_wheel  => Wheel->new('steer', 'brake'),
529                        left_rear_wheel   => Wheel->new('drive', 'brake'),
530                        right_front_wheel => Wheel->new('steer', 'brake'),
531                        right_rear_wheel  => Wheel->new('drive', 'brake'),
532                        flywheel          => Flywheel->new(),
533                        mp3               => MP3::Player->new(),
534                      }, $_[0];
535        }
536
537The Flywheel class would probably have its own C<brake> method (to
538harvest motive energy from the flywheel) and MP3::Player might have its
539own C<drive> method (to switch between storage devices).
540
541An C<AUTOLOAD> redispatch such as that shown above would then fail very
542badly. Whilst it would prove merely annoying to have one's music skip
543tracks (C<$self-E<gt>{mp3}-E<gt>drive(+10)>) every time one accelerated
544(C<$self-E<gt>{right_rear_wheel}-E<gt>drive(+10)>), it might be disastrous to
545attempt to suck energy out of the flywheel
546(C<$self-E<gt>{flywheel}-E<gt>brake()>) whilst the brakes are trying to feed it
547back in (C<$self-E<gt>{right_rear_wheel}-E<gt>brake()>).
548
549Class-action lawyers I<love> this kind of programming.
550
551
552=head1 DESCRIPTION
553
554The Class::Delegation module simplifies the creation of
555delegation-based class hierarchies, allowing
556a method to be redispatched:
557
558=over 4
559
560=item *
561
562to a single nominated attribute,
563
564=item *
565
566to a collection of nominated attributes in parallel, or
567
568=item *
569
570to any attribute that can handle the message.
571
572=item *
573
574the object itself
575
576=back
577
578These three delegation mechanisms can be specified for:
579
580=over 4
581
582=item *
583
584a single method
585
586=item *
587
588a set of nominated methods collectively
589
590=item *
591
592any as-yet-undelegated methods
593
594=item *
595
596all methods, delegated or not.
597
598=back
599
600=head2 The syntax and semantics of delegation
601
602To cause a hash-based class to delegate method invocations to its
603attributes, the Class::Delegation module is imported into the class, and
604passed a list of method/handler mappings that specify the delegation
605required. Each mapping consists of between one and three key/value
606pairs. For example:
607
608        package Car;
609
610        use Class::Delegation
611                send => 'steer',
612                  to => ["left_front_wheel", "right_front_wheel"],
613
614                send => 'drive',
615                  to => ["right_rear_wheel", "left_rear_wheel"],
616		  as => ["rotate_clockwise", "rotate_anticlockwise"]
617
618                send => 'power',
619                  to => 'flywheel',
620                  as => 'brake',
621
622                send => 'brake',
623                  to => qr/.*_wheel$/,
624
625                send => qr/^MP_(.+)/,
626                  to => 'mp3',
627                  as => sub { $1 },
628
629                send => -OTHER,
630                  to => 'mp3',
631
632                send => 'debug',
633                  to => -ALL,
634                  as => 'dump',
635
636                send => -ALL,
637                  to => 'logger',
638                ;
639
640=head2 Specifying methods to be delegated
641
642The names of methods to be redispatched can be
643specified using the C<'send'> key. They may be specified as single strings, arrays of strings, regular
644expressions, subroutines, or as one of the two special names: C<-ALL> and C<-OTHER>.
645A single string specifies a single method to be delegated in some way.
646The other alternatives specify sets of methods
647that are to share the associated delegation semantics. That set
648of methods may be specified:
649
650=over 4
651
652=item *
653
654explicitly, by an array (the set consists of those method calls whose names
655appear in the array),
656
657=item *
658
659implicitly, by a regex (the set consists of those method calls whose names match the pattern),
660
661=item *
662
663procedurally, by a subroutine (the set consists of any method calls for which the subroutine
664returns a true value, when passed the method invocant, the method name, and the
665arguments with which the method was invoked),
666
667=item *
668
669generically, by C<-ALL> (the set consists of every method call -- excluding calls
670to C<DESTROY> --  that is not handled by an
671explicit method of the class),
672
673=item *
674
675exclusively, by C<-OTHER> (the set consists of every method call -- excluding calls
676to C<DESTROY> -- that is not successfully
677delegated by any earlier mapping in the C<use Class::Delegation> list).
678
679=back
680
681The exclusion of calls to C<DESTROY> in the last two cases ensures that automatically
682invoked destructor calls are not erroneously delegated. C<DESTROY> calls I<can> be
683delegated through any of the other specification mechanisms.
684
685=head2 Specifying attributes to be delegated to
686
687The actual delegation behaviour is determined by the attributes to which these
688methods are to be delegated. This information can be specified via the C<'to'>
689key, using a string, an array, a regex, a subroutine, or the special flag
690C<-ALL>. Normally the delegated method that is invoked on the specified attribute (or attributes)
691has the same name as the original call, and is invoked in the same calling
692context (void, scalar, or list).
693
694If the attribute is specified via a single string, that string is taken
695as the name of the attribute to which the associated method (or methods)
696should be delegated. For
697example, to delegate invocations of C<$self-E<gt>power(...)> to
698C<$self-E<gt>{flywheel}-E<gt>power(...)>:
699
700        use Class::Delegation
701            send => 'power',
702              to => 'flywheel';
703
704If the attribute is specified via a single string that starts with C<"->...">
705then that string is taken as specifying the name of a I<method> of the
706current object. That method is called and is expected to return an
707object. The original method that was being delegated is then delegated to that
708object. For example, to delegate invocations of C<$self-E<gt>power(...)> to
709C<$self-E<gt>flywheel()-E<gt>power(...)>:
710
711        use Class::Delegation
712            send => 'power',
713              to => '->flywheel';
714
715Since this syntax is a little obscure (and not a little ugly),
716the same effect can also be obtained like so:
717
718        use Class::Delegation
719            send => 'power',
720              to => -SELF->flywheel;
721
722
723An array reference can be used in the attribute position to specify the
724a list of attributes, I<all of which> are delegated to -- in sequence
725they appear in the list. Note that each element of the array is
726processed recursively, so it may contain any of the other attribute
727specifiers described in this section (or, indeed, a nested array of
728attribute specifiers)
729
730For example, to distribute invocations of C<$self-E<gt>drive(...)> to both
731C<$self-E<gt>{left_rear_wheel}-E<gt>drive(...)> and
732 C<$self-E<gt>{right_rear_wheel}-E<gt>drive(...)>:
733
734        use Class::Delegation
735            send => 'drive',
736              to => ["left_rear_wheel", "right_rear_wheel"];
737
738Note that using an array to specify parallel delegation has an effect on the return
739value of the original method. In a scalar context, the original call returns a reference to
740an array containing the (scalar context) return values of each of the calls. In
741a list context, the original call returns a list of array references
742containing references to the individual (list context) return lists of the calls. So, for example, if a
743class's C<cost> method were delegated like so:
744
745        use Class::Delegation
746                send => 'cost',
747                  to => ['supplier', 'manufacturer', 'distributor'];
748
749then the total cost could be calculated like this:
750
751        use List::Util 'sum';
752        $total = sum @{$obj->cost()};
753
754Specifying the attribute as a regular expression causes the associated
755method to be delegated to any attribute whose name matches the pattern.
756Attributes are tested for such a match -- and delegated to -- in the
757internal order of their hash (i.e. in the sequence returned by C<keys>).  For
758example, to redispatch C<brake> calls to every attribute whose name ends in C<"_wheel">:
759
760        send => 'brake',
761          to => qr/.*_wheel$/,
762
763If a subroutine reference is used as the C<'to'> attribute specifier, it is passed the
764invocant, the name of the method, and the argument list. It is expected to
765return either a value specifying the correct attribute name (or names). As with an
766array, the value returned may be any valid attribute specifier (including
767another subroutine reference) and is iteratively processed to determine the
768correct target(s) for delegation.
769
770A subroutine may also return a reference to an object, in which case the
771subroutine is delegated to that object (rather than to an attribute of
772the current object). This can be useful when the actual delegation target
773is more complex than just a direct attribute. For example:
774
775	send => 'start',
776	  to => sub { $_[0]{ignition}{security}[$_[0]->next_key] },
777
778
779If the C<-ALL> flag is used as the name of the attribute, the method
780is delegated to all attributes of the object (in their C<keys> order). For
781example, to forward debugging requests to every attribute in turn:
782
783        send => 'debug',
784          to => -ALL,
785
786
787=head2 Specifying the name of a delegated method
788
789Sometimes it is necessary to invoke an attribute's method through a
790different name than that of the original delegated method. The C<'as'>
791key facilitates this type of method name translation in any delegation.
792The value associated with an C<'as'> key specifies the name of the
793method to be invoked, and may be a string, an array, or a subroutine.
794
795If a string is provided, it is used as the new name of the delegated method.
796For example, to cause calls to C<$self-E<gt>power(...)>
797to be delegated to C<$self-E<gt>{flywheel}-E<gt>brake(...)>:
798
799        send => 'power',
800          to => 'flywheel',
801          as => 'brake',
802
803If an array is given, it specifies a list of delegated method names.
804If the C<'to'> key specifies a single attribute, each method in the list is
805invoked on that one attribute. For example:
806
807        send => 'boost',
808          to => 'flywheel',
809          as => ['override', 'engage', 'discharge'],
810
811would sequentially call:
812
813        $self->{flywheel}->override(...);
814        $self->{flywheel}->engage(...);
815        $self->{flywheel}->discharge(...);
816
817If both the C<'to'> key and the C<'as'> key specify multiple values, then
818each attribute and method name form a pair, which is invoked. For example:
819
820        send => 'escape',
821          to => ['flywheel', 'smokescreen'],
822          as => ['engage',   'release'],
823
824would sequentially call:
825
826        $self->{flywheel}->engage(...);
827        $self->{smokescreen}->release(...);
828
829If a subroutine reference is used as the C<'as'> specifier, it is passed the
830invocant, the name of the method, and the argument list, and is expected to
831return a string that will be used as the method name. For example, to
832strip method calls of a C<"driver_..."> prefix and delegate them to the
833C<'driver'> attribute:
834
835        send => sub { substr($_[1],0,7) eq "driver_" },
836          to => 'driver',
837          as => sub { substr($_[1],7) }
838
839or:
840
841        send => qr/driver_(.*)/,
842          to => 'driver',
843          as => sub { $1 }
844
845
846=head2 Delegation to self
847
848Class::Delegation can also be used to delegate methods back to the original
849object, using the C<-SELF> option with the C<'to'> key. For example, to
850redirect any call to C<overdrive> so to invoke the C<boost> method instead:
851
852       send => 'overdrive',
853         to => -SELF,
854         as => 'boost',
855
856Note that this only works if the object I<does not> already have an
857C<overdrive> method.
858
859As with other delegations, a single call can be redelegated-to-self as
860multiple calls.  For example:
861
862       send => 'emergency',
863         to => -SELF,
864         as => ['overdrive', 'launch_rockets'],
865
866
867=head2 Handling failure to delegate
868
869If a method cannot be successfully delegated through any of its mappings,
870Class::Delegation will ignore the call and the built-in
871C<AUTOLOAD> mechanism will attempt to handle it instead.
872
873
874=head1 EXAMPLES
875
876Delegation is a useful replacement for inheritance in a number of contexts.
877This section outlines five of the most common uses.
878
879=head2 Simulating single inheritance
880
881Unlike most other OO languages, inheritance in Perl only works well when
882the base class has been I<designed> to be inherited from. If the attributes
883of a prospective base class are inaccessible, or the implementation is
884not extensible (e.g. a blessed scalar or regular expression), or the
885base class's constructor does not use the two-argument form C<bless>, it
886will probably be impractical to inherit from the class.
887
888Moreover, in many cases, it is not possible to tell -- without a detailed
889inspection of a base class's implementation -- whether such a class can easily be
890inherited. This inability to reliably treat classes as encapsulated and
891implementation-independent components seriously undermines the usability
892of object-oriented Perl.
893
894But since inheritance in Perl merely specifies where a class is to look next
895if a suitable method is not found in its own package [3], it is often possible
896to replace derivation with aggregation and use a delegated attribute instead.
897
898For example, it is possible to simulate the inheritance of the class Base
899via a delegated attribute:
900
901        package Derived;
902        use Class::Delegation send => -ALL, to => 'base';
903
904        sub new {
905                my ($class, $new_attr1, $new_attr2, @base_args) = @_;
906                bless { attr1 => $new_attr1,
907                        attr2 => $new_attr2,
908                        base  => Base->new(@base_args),
909                      }, $class;
910        }
911
912Now any method that is not present in Derived is delegated to the Base object
913referred to by the C<base> attribute, just as it would have been if
914Derived actually inherited from Base.
915
916This technique works in situations where the functionality of the Base methods
917is non-polymorphic with respect to their invocant. That is, if an inherited
918method in class Base were to interrogate the class of the object on which it was called,
919it would find a Derived object. But a delegated method in class Base will find a Base object.
920This is not the usual behaviour in OO Perl, but is correct and appropriate under the earlier
921assumption that Base has not been designed to be inherited from -- and must therefore
922always expect a Base class object as its invocant.
923
924
925=head2 Replacing method dispatch semantics
926
927Another situation in which delegation is preferable to inheritance is
928where inheritance I<is> feasible, but Perl's standard dispatch semantics
929-- left-most, depth-first priority of method dispatch -- are
930inappropriate.
931
932For example, if various base classes in a class hierarchy provide a C<dump_info> method
933for debugging purposes, then a derived class than multiply inherits from two or more
934of those classes will only dispatch calls to C<dump_info> to the left-most ancestor's
935method. This is unlikely to be the desired behaviour.
936
937Using delegation it is possible to cause calls to C<dump_info> to invoke the corresponding
938methods of I<all> the base classes, whilst all other method calls are dispatched left-most and
939depth-first, as normal:
940
941        package Derived;
942        use Class::Delegation
943                send => 'dump_info',
944                  to => -ALL,
945
946                send => -OTHER,
947                  to => 'base1',
948
949                send => -OTHER,
950                  to => 'base2',
951                ;
952
953        sub new {
954                my ($class, %named_args) = @_;
955                bless { base1 => Base1->new(%named_args),
956                        base2 => Base2->new(%named_args),
957                      }, $class;
958        }
959
960Note that the semantics of C<send =E<gt> -OTHER> ensure that only one of the
961two base classes is delegated a method. If C<base1> is able to handle
962a particular method delegation, then it will have been dispatched when
963the C<-OTHER> governing C<base2> is reached, so the second C<-OTHER> will
964ignore it.
965
966
967=head2 Simulating multiple inheritance of pseudohashs
968
969Another situation in which multiple inheritance can cause trouble is
970where a class needs to inherit from two base classes that are both
971implemented via pseudohashes. Because each pseudohash base class will
972assume that I<its> attributes start from index C<1> of the pseudohash
973array, the methods of the two classes would contend for the same
974attribute slots in the derived class. Hence the C<use base> pragma
975detects cases where two ancestral classes are pseudohash-based and
976rejects them (terminally).
977
978Delegation provides a convenient way to provide the effects of
979pseudohash multiple inheritance, without the attendant problems. For example:
980
981        package Derived;
982        use Class::Delegation
983                send => -ALL,
984                  to => 'pseudobase1',
985
986                send => -OTHER,
987                  to => 'pseudobase2',
988                ;
989
990        sub new {
991                my ($class, %named_args) = @_;
992                bless { pseudobase1 => Pseudo::Base1->new(%named_args),
993                        pseudobase2 => Pseudo::Base2->new(%named_args),
994                      }, $class;
995        }
996
997As in the previous example, only one of the two base classes
998is delegated a method. The C<-ALL> associated with C<pseudobase1>
999attempts to delegate every method to that attribute, then the C<-OTHER>
1000associated with C<pseudobase2> catches any methods that cannot be
1001handled by C<pseudobase1>.
1002
1003
1004
1005=head2 Adapting legacy code
1006
1007Because the C<'as'> key can take a subroutine, it is also possible to
1008use a delegating class to adapt the interface of an existing class. For example,
1009a class with separate "get" and "set" accessors:
1010
1011        class DogTag;
1012
1013        sub get_name   { return $_[0]->{name} }
1014        sub set_name   { $_[0]->{name} = $_[1] }
1015
1016        sub get_rank   { return $_[0]->{rank} }
1017        sub set_rank   { $_[0]->{rank} = $_[1] }
1018
1019        sub get_serial { return $_[0]->{serial} }
1020        sub set_serial { $_[0]->{serial} = $_[1] }
1021
1022        # etc.
1023
1024could be trivially adapted to provide combined get/set accessors like so:
1025
1026        class DogTag::SingleAccess;
1027
1028        use Class::Delegation
1029                send => -ALL
1030                  to => 'dogtag',
1031                  as => sub {
1032                             my ($invocant, $method, @args) = @_;
1033                             return @args ? "set_$method" : "get_$method"
1034                         },
1035                ;
1036
1037        sub new { bless { dogtag => DogTag->new(@_[1..$#_) }, $_[0] }
1038
1039Here, the C<'as'> subroutine determines whether an "new value" argument
1040was passed to the original method, delegating to the C<set_...> method if so,
1041and to the C<get_...> method otherwise.
1042
1043
1044=head2 Multiplexing a facade
1045
1046The ability to use regular expressions to specify method names, and
1047subroutines to indicate the attributes and attribute methods to which
1048they are delegated, opens the possibility of creating a class that
1049acts as a collective front-end for several others. For example:
1050
1051        package Bilateral;
1052
1053        %Bilateral = ( left  => 'Levorotatory',
1054                       right => 'Dextrorotatory',
1055                     );
1056
1057        use Class::Delegation
1058                send => qr/(left|right)_(.*)/,
1059                  to => sub { $1 },
1060                  as => sub { $2 },
1061                ;
1062
1063        sub AUTOLOAD  {
1064                carp "$AUTOLOAD does not begin with 'left_...' or 'right_...'"
1065        },
1066
1067
1068The Bilateral class now forwards all I<class> method calls that are prefixed
1069with C<"left_..."> to the Laevorotatory class, and all those prefixed with
1070C<"right_..."> to the Dextrorotatory class. Any calls that cannot be dispatched
1071are caught and ignored (with a warning) by the C<AUTOLOAD>.
1072
1073The mechanism by which the class method dispatch is achieved is perhaps a little obscure.
1074Consider the invocation of a class method:
1075
1076        Bilateral->left_rotate(45);
1077
1078Here, the invocant is the string C<"Bilateral">, rather than a blessed object. Thus,
1079when Class::Delegation forwards the call to:
1080
1081        $self->{$1}->$2(45);
1082
1083the effect is the same as calling:
1084
1085        "Bilateral"->{left}->rotate(45);
1086
1087This invokes a little-known feature of the C<-E<gt>> operator [4]. If a hash access is
1088performed on a string, that string is taken as a symbolic
1089reference to a package hash variable in the current package. Thus the above call is internally translated to:
1090
1091        ${"Bilateral"}{left}->rotate(45);
1092
1093which is equivalent to the class method call:
1094
1095        Levorotatory->rotate(45);
1096
1097=head1 AUTHOR
1098
1099Damian Conway (damian@conway.org)
1100
1101=head1 BUGS
1102
1103There are undoubtedly serious bugs lurking somewhere in this code.
1104Bug reports and other feedback are most welcome.
1105
1106=head1 COPYRIGHT
1107
1108       Copyright (c) 2001, Damian Conway. All Rights Reserved.
1109    This module is free software. It may be used, redistributed
1110        and/or modified under the same terms as Perl itself.
1111