Skip to content

Instantly share code, notes, and snippets.

@alabamenhu
Last active August 9, 2020 22:58
Show Gist options
  • Save alabamenhu/1b60015fbaabc819aeabff4d112678e1 to your computer and use it in GitHub Desktop.
Save alabamenhu/1b60015fbaabc819aeabff4d112678e1 to your computer and use it in GitHub Desktop.
How to (mostly safely) add a custom coercer to another class
class Percent {
has $.value;
method new (Numeric $value) { self.bless: :value($value * 100) }
# Coercers from Percent
method Str { $.value ~ "%" }
method Numeric { $.value / 100 } 
# Coercers into Percent
Int.^add_fallback(
anon sub condition (Int $object, Str $method-name) { $method-name eq 'Percent' }, # checks if our fallback applies
anon sub calculator (Int $object, Str $method-name) {
# when it does, return the coercion method
return method (Int: --> Percent) {
return Percent.new(self)
}
}
);
Rat.^add_fallback(
anon sub condition (Rat $object, Str $method-name) { $method-name eq 'Percent' }, # checks if our fallback applies
anon sub calculator (Rat $object, Str $method-name) {
# when it does, return the coercion method
return method (Rat: --> Percent) {
return Percent.new(self)
}
}
);
}
# Examples
my $half = 0.5;
my $whole = 1;
my $half-as-percent = $half.Percent;
my $whole-as-percent = $whole.Percent;
say "$half is a ", $half.WHAT;
say "$whole is a ", $whole.WHAT;
say "$half-as-percent is a ", $half-as-percent.WHAT;
say "$whole-as-percent is a ", $whole-as-percent.WHAT;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment