Created
December 22, 2019 21:38
-
-
Save lizmat/31a39891dce0d8ed07bd4739846fa047 to your computer and use it in GitHub Desktop.
Attempting to make handles trait a method on Attribute
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
diff --git a/src/core.c/Attribute.pm6 b/src/core.c/Attribute.pm6 | |
index 1de2f2074..c544307e3 100644 | |
--- a/src/core.c/Attribute.pm6 | |
+++ b/src/core.c/Attribute.pm6 | |
@@ -218,6 +218,89 @@ my class Attribute { # declared in BOOTSTRAP | |
method set_why($why) { | |
$!why := $why; | |
} | |
+ | |
+ role Handles { | |
+ has $.handles; | |
+ | |
+ method set_handles($expr) { | |
+ $!handles := $expr; | |
+ } | |
+ | |
+ method add_delegator_method($attr: $pkg, $meth_name, $call_name) { | |
+ my $meth := method (|c) is rw { | |
+ $attr.get_value(self)."$call_name"(|c) | |
+ }; | |
+ $meth.set_name($meth_name); | |
+ $pkg.^add_method($meth_name, $meth); | |
+ } | |
+ | |
+ method apply_handles($attr: Mu $pkg) { | |
+ sub applier($expr) { | |
+ if $expr.defined() { | |
+ if nqp::istype($expr,Str) { | |
+ self.add_delegator_method($pkg, $expr, $expr); | |
+ } | |
+ elsif nqp::istype($expr,Pair) { | |
+ self.add_delegator_method($pkg, $expr.key, $expr.value); | |
+ } | |
+ elsif nqp::istype($expr,Positional) { | |
+ for $expr.list { | |
+ applier($_); | |
+ } | |
+ 0; | |
+ } | |
+ elsif nqp::istype($expr, Whatever) { | |
+ $pkg.^add_fallback( | |
+ -> $obj, $name { | |
+ so $attr.get_value($obj).can($name); | |
+ }, | |
+ -> $obj, $name { | |
+ -> $self, |c { | |
+ $attr.get_value($self)."$name"(|c) | |
+ } | |
+ }); | |
+ } | |
+ elsif nqp::istype($expr, HyperWhatever) { | |
+ $pkg.^add_fallback( | |
+ -> $, $ --> True { }, | |
+ -> $obj, $name { | |
+ -> $self, |c { | |
+ $attr.get_value($self)."$name"(|c) | |
+ } | |
+ }); | |
+ } | |
+ else { | |
+ $pkg.^add_fallback( | |
+ -> $obj, $name { | |
+ ?($name ~~ $expr) | |
+ }, | |
+ -> $obj, $name { | |
+ -> $self, |c { | |
+ $attr.get_value($self)."$name"(|c) | |
+ } | |
+ }); | |
+ } | |
+ } | |
+ else { | |
+ $pkg.^add_fallback( | |
+ -> $obj, $name { | |
+ ?$expr.can($name) | |
+ }, | |
+ -> $obj, $name { | |
+ -> $self, |c { | |
+ $attr.get_value($self)."$name"(|c) | |
+ } | |
+ }); | |
+ } | |
+ } | |
+ applier($!handles); | |
+ } | |
+ } | |
+ | |
+ method add-delegator(\delegatees --> Nil) { | |
+ self does Handles; | |
+ self.set_handles(delegatees) | |
+ } | |
} | |
# does trait | |
@@ -238,4 +321,7 @@ multi sub trait_mod:<does>(Attribute:D $a, Mu:U $role) { | |
} | |
} | |
+multi sub trait_mod:<handles>(Attribute:D $target, $thunk) { | |
+} | |
+ | |
# vim: ft=perl6 expandtab sw=4 | |
diff --git a/src/core.c/traits.pm6 b/src/core.c/traits.pm6 | |
index 7a72f41da..bc4e63d9f 100644 | |
--- a/src/core.c/traits.pm6 | |
+++ b/src/core.c/traits.pm6 | |
@@ -418,84 +418,7 @@ multi sub trait_mod:<returns>(Routine:D $target, Mu:U $type) { | |
proto sub trait_mod:<handles>($, $, *%) {*} | |
multi sub trait_mod:<handles>(Attribute:D $target, $thunk) { | |
- $target does role { | |
- has $.handles; | |
- | |
- method set_handles($expr) { | |
- $!handles := $expr; | |
- } | |
- | |
- method add_delegator_method($attr: $pkg, $meth_name, $call_name) { | |
- my $meth := method (|c) is rw { | |
- $attr.get_value(self)."$call_name"(|c) | |
- }; | |
- $meth.set_name($meth_name); | |
- $pkg.^add_method($meth_name, $meth); | |
- } | |
- | |
- method apply_handles($attr: Mu $pkg) { | |
- sub applier($expr) { | |
- if $expr.defined() { | |
- if nqp::istype($expr,Str) { | |
- self.add_delegator_method($pkg, $expr, $expr); | |
- } | |
- elsif nqp::istype($expr,Pair) { | |
- self.add_delegator_method($pkg, $expr.key, $expr.value); | |
- } | |
- elsif nqp::istype($expr,Positional) { | |
- for $expr.list { | |
- applier($_); | |
- } | |
- 0; | |
- } | |
- elsif nqp::istype($expr, Whatever) { | |
- $pkg.^add_fallback( | |
- -> $obj, $name { | |
- so $attr.get_value($obj).can($name); | |
- }, | |
- -> $obj, $name { | |
- -> $self, |c { | |
- $attr.get_value($self)."$name"(|c) | |
- } | |
- }); | |
- } | |
- elsif nqp::istype($expr, HyperWhatever) { | |
- $pkg.^add_fallback( | |
- -> $, $ --> True { }, | |
- -> $obj, $name { | |
- -> $self, |c { | |
- $attr.get_value($self)."$name"(|c) | |
- } | |
- }); | |
- } | |
- else { | |
- $pkg.^add_fallback( | |
- -> $obj, $name { | |
- ?($name ~~ $expr) | |
- }, | |
- -> $obj, $name { | |
- -> $self, |c { | |
- $attr.get_value($self)."$name"(|c) | |
- } | |
- }); | |
- } | |
- } | |
- else { | |
- $pkg.^add_fallback( | |
- -> $obj, $name { | |
- ?$expr.can($name) | |
- }, | |
- -> $obj, $name { | |
- -> $self, |c { | |
- $attr.get_value($self)."$name"(|c) | |
- } | |
- }); | |
- } | |
- } | |
- applier($!handles); | |
- } | |
- }; | |
- $target.set_handles($thunk()); | |
+ $target.add-delegator($thunk()); | |
} | |
multi sub trait_mod:<handles>(Method:D $m, &thunk) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment