Skip to content

Instantly share code, notes, and snippets.

@zoffixznet

zoffixznet/p6.p6 Secret

Created November 30, 2017 23:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoffixznet/ba48a57bb51ce983b3aa7b9039b164a7 to your computer and use it in GitHub Desktop.
Save zoffixznet/ba48a57bb51ce983b3aa7b9039b164a7 to your computer and use it in GitHub Desktop.
class Proxee {
use MONKEY-GUTS;
proto method new(|) { * }
class Proxee::X::CannotBindStore is Exception {
method message {
'A Proxee cannot use :BIND and :STORE at the same time'
}
}
multi method new(\coercer where {.HOW ~~ Metamodel::CoercionHOW}) {
my \from = coercer.^constraint_type;
my \to = coercer.^target_type;
my $to-name := to.^name;
my $STORAGE;
Proxy.new: :FETCH{ $STORAGE }, STORE => -> $, \v {
die X::TypeCheck.new: :got(v.WHAT), :expected(from), :operation<Proxee>
unless nqp::istype(v, from); # on 2017.11 about 13x faster than ~~
nqp::istype(v, to) ?? ($STORAGE := v)
!! ($STORAGE := v."$to-name"());
$STORAGE
}
}
multi method new (:&BIND, :&STORE, :&FETCH) {
&BIND and &STORE and die Proxee::X::CannotBindStore.new;
my $*PROXEE;
my &final-store := &STORE || &BIND || { $*PROXEE := $_ };
my &fetch = &FETCH || { $*PROXEE };
Proxy.new: :FETCH{ fetch }, STORE => -> $, \v is raw { final-store v }
}}
my $v := Proxee.new: :STORE{ $*PROXEE := $_² };
$v = 42;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment