@@ -598,6 +598,91 @@ $test.frob; # calls the frob method of Child rather than Parent
598
598
# OUTPUT: «the child's somewhat more fancy frob is called»
599
599
= end code
600
600
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: «23456»
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
+
601
686
X < |new (method) >
602
687
= head2 Object construction
603
688
0 commit comments