Skip to content

Instantly share code, notes, and snippets.

@rcmlz
Last active October 24, 2023 09:15
Show Gist options
  • Save rcmlz/ddbffbcad5ce3c10aa5203db6b73f46e to your computer and use it in GitHub Desktop.
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
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