Last active
October 24, 2023 09:15
-
-
Save rcmlz/ddbffbcad5ce3c10aa5203db6b73f46e to your computer and use it in GitHub Desktop.
Class, Subclass, Role Demo of Raku - interestingly a Role can be attached to a Class as well as to an Instance of Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Client { | |
has @.pairs-of-shapes; | |
method intersect-all { | |
gather { | |
for @!pairs-of-shapes -> ($s1, $s2) { | |
take $s1.intersect($s2) | |
} | |
} | |
} | |
} | |
#| Shape ∩ Shape -> Shape | |
class Shape { | |
#| Universal Shape ∩ Shape --> Shape | |
multi method intersect(Shape $s --> Shape){ | |
return Shape | |
} | |
} | |
#|« Shape ∩ Rectangle -> Shape | |
Rectangle ∩ Shape -> Shape | |
Rectangle ∩ Rectangle -> Rectangle » | |
class Rectangle is Shape { | |
#| Specialized Rectangle ∩ Rectangle --> Rectangle | |
multi method intersect(Rectangle $r --> Rectangle){ | |
return Rectangle | |
} | |
} | |
# Now assume that the complex & mighty classes Shape and Rectangle must NOT be modified | |
# - e.g. because they are externally purchased, expensive library | |
# but there is a new Nobel price winning algorithm to Rectangle ∩ Rectangle -> Triangle we want to use | |
# We have two options: | |
# a.) extending Rectangle instances using a role | |
# b.) creating a new subclass - overwriting multi method intersect or simply re-using the role | |
class Triangle { } | |
role Improved { | |
#| Nobel price winning Rectangle ∩ Rectangle --> Triangle | |
multi method intersect(Rectangle $r --> Triangle){ | |
return Triangle | |
} | |
} | |
# Initial implementation | |
my @arr-initial of Shape = Shape.new, Rectangle.new; | |
# a.) simply using role and extend Instances of Rectangle | |
my @arr-role of Shape = Shape.new, Rectangle.new does Improved; | |
# b.) creating a new subclass - here by re-using the Role | |
class Rectangle-Improved is Rectangle does Improved { } | |
my @arr-subclass of Shape = Shape.new, Rectangle-Improved.new; | |
use Test; | |
my @testdata = (@arr-initial, (Shape, Shape, Shape, Rectangle)), | |
(@arr-role , (Shape, Shape, Shape, Triangle)), | |
(@arr-subclass, (Shape, Shape, Shape, Triangle)); | |
for @testdata -> (@in, @expected) { | |
my @pairs-of-shapes = (@in X @in); | |
is-deeply Client.new(:@pairs-of-shapes).intersect-all, @expected | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment