Skip to content

Commit f8da8ad

Browse files
authored
Merge pull request #3257 from uzluisf/master
Add small section about delegation Closes #3255
2 parents 2c24bc9 + db7481c commit f8da8ad

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

doc/Language/objects.pod6

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,91 @@ $test.frob; # calls the frob method of Child rather than Parent
598598
# OUTPUT: «the child's somewhat more fancy frob is called␤»
599599
=end code
600600
601+
X<|delegation (trait handles)>
602+
=head2 Delegation
603+
604+
Delegation is a technique whereby a member of an object (the I«delegatee») is
605+
evaluated in the context of another original object (the I«delegator»). In other
606+
words, all method calls on the delegator are I«delegated» to the delegatee.
607+
608+
In Raku, delegation is specified by applying the L«handles|/language/typesystem#trait_handles»
609+
trait to an attribute. The arguments provided to the trait specify the methods
610+
the current object and the delegatee object will have in common. Instead of a
611+
list of method names, a C<Pair> (for renaming), a list of C<Pairs>, a C<Regex>
612+
or a C<Whatever> can be provided.
613+
614+
=begin code
615+
class Book {
616+
has Str $.title;
617+
has Str $.author;
618+
has Str $.language;
619+
has Cool $.publication;
620+
}
621+
622+
class Product {
623+
has Book $.book handles('title', 'author', 'language', year => 'publication');
624+
}
625+
626+
my $book = Book.new:
627+
:title<Dune>,
628+
:author('Frank Herbert'),
629+
:language<English>,
630+
:publication<1965>
631+
;
632+
633+
given Product.new(:$book) {
634+
say .title; # OUTPUT: «Dune␤»
635+
say .author; # OUTPUT: «Frank Herbert␤»
636+
say .language; # OUTPUT: «English␤»
637+
say .year; # OUTPUT: «1965␤»
638+
}
639+
=end code
640+
641+
In the example above, the class C«Product» defines the attribute C«$.book»
642+
and mark it with the C«handles» trait to specify the methods that will be
643+
forwarded to the class C«Book» whenever they're invoked on an instance
644+
object of the C«Product» class. There are a few things to notice here:
645+
646+
=item We didn't write any methods inside the C«Product» class that we invoked
647+
in its instance object. Instead, we instructed the class to delegate a call to
648+
any those methods to the C«Book» class.
649+
650+
=item We've specified the method names C«title», C«author», and C«language»
651+
as they appear in the C«Book» class. On the other hand, we've renamed
652+
the C«publication» method to C«year» by providing the appropriate C«Pair».
653+
654+
Delegation can be used as an alternative to inheritance by delegating
655+
to the parent class and not inheriting all of its methods. For example, the
656+
following C«Queue» class delegates several methods proper of queues
657+
to the L«Array|/type/Array» class while also providing a preferred interface for
658+
a few of those methods (e.g., C«enqueue» for C«push»):
659+
660+
=begin code
661+
class Queue {
662+
has @!q handles(
663+
enqueue => 'push', dequeue => 'shift',
664+
'push', 'shift', 'head', 'tail', 'elems', 'splice'
665+
);
666+
667+
method gist {
668+
'[' ~ @!q.join(', ') ~ ']'
669+
}
670+
}
671+
672+
my Queue $q .= new;
673+
$q.enqueue($_) for 1..5;
674+
$q.push(6);
675+
say $q.shift; # OUTPUT: «1␤»
676+
say $q.dequeue while $q.elems; # OUTPUT: «2␤3␤4␤5␤6␤»
677+
678+
$q.enqueue($_) for <Perl Python Raku Ruby>;
679+
say $q.head; # OUTPUT: «Perl␤»
680+
say $q.tail; # OUTPUT: «Ruby␤»
681+
say $q; # OUTPUT: «[Perl, Python, Raku, Ruby]␤»
682+
$q.dequeue while $q.elems;
683+
say $q; # OUTPUT: «[]␤»
684+
=end code
685+
601686
X<|new (method)>
602687
=head2 Object construction
603688

0 commit comments

Comments
 (0)