Skip to content

Instantly share code, notes, and snippets.

@gfldex
Created February 13, 2021 13:58
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 gfldex/09e8db29bdf1524d2da95414ae96443f to your computer and use it in GitHub Desktop.
Save gfldex/09e8db29bdf1524d2da95414ae96443f to your computer and use it in GitHub Desktop.
use v6.e.PREVIEW;
use MONKEY-TYPING;
# augment class Any {
# method chain {
# class Chainer {
# has $.the-object;
# method FALLBACK($name, *@a) {
# my $o = $.the-object;
# if @a {
# for @a -> $e {
# $o = $o."$name"($e, |%_);
# }
# } elsif %_ {
# for %_ -> %p {
# $o = $o."$name"(|%p);
# }
# } else {
# # XXX error handling
# }
#
# $o
# }
# }
#
# Chainer.new(the-object => self)
# }
# }
# IO::Path.HOW.compose(IO::Path);
# DateTime.HOW.compose(DateTime);
# sub chain($self) {
# class :: is Mu {
# has $.the-object;
# method FALLBACK($name, *@a) {
# my $o = $.the-object;
# my \m = $o.^lookup($name) orelse {
# my $bt = Backtrace.new;
# my $idx = $bt.next-interesting-index($bt.next-interesting-index + 1);
# (X::Method::NotFound.new(:method($name), :typename($o.^name)) but role :: { method vault-backtrace { False }}).throw(Backtrace.new($idx + 1));
# }
# if @a {
# for @a -> $e {
# # $o = $o.^lookup($name).($o, $e, |%_);
# $o = $o."$name"($e, |%_);
# }
# } elsif %_ {
# for %_ -> %p {
# $o = $o."$name"(|%p);
# }
# } else {
# # XXX error handling
# }
#
# $o
# }
# }.new(the-object => $self)
# }
#
# constant no-argument-given = Mu.new;
# sub try($self, Mu $alternate-value = no-argument-given) {
# class :: is Mu {
# has $.the-object;
# method WHY { 'This is a wrapper for `sub defuse` around ' ~ $.the-object.WHAT.gist ~ '.' }
# method gist { self.WHY }
# method FALLBACK($name, |c) {
# my $o = $.the-object;
# my \m = $o.^lookup($name) orelse {
# my $bt = Backtrace.new;
# my $idx = $bt.next-interesting-index($bt.next-interesting-index + 1);
# (X::Method::NotFound.new(:method($name), :typename($o.^name)) but role :: { method vault-backtrace { False }}).throw(Backtrace.new($idx + 1));
# }
#
# try {
# $o = $o."$name"(|c);
# }
#
# $! ~~ Exception
# ?? $alternate-value.WHICH eqv no-argument-given.WHICH
# ?? $o.WHAT
# !! $alternate-value
# !! $o
# }
# }.new(the-object => $self)
# }
#
#
# sub pry(Mu $the-object is raw) {
# class :: is Mu {
# has $.the-object;
# method WHY { 'This is a wrapper for `sub pry` around ' ~ $.the-object.WHAT.gist ~ '.' }
# method gist { self.WHY }
# method FALLBACK($name) is rw {
# use nqp;
# nqp::getattr($.the-object, $.the-object.WHAT, '$!' ~ $name)
# }
# }.new(:$the-object)
# }
#
# '/home/dex'.IO.&chain.add(<tmp foo.txt>).say;
# '/home/dex'.IO.&chain.add('tmp').add('foo.txt').say;
#
# {
#
# my $d = now.DateTime;
# say $d;
# say $d.later(:1hour).later(:30minutes);
#
# say $d.&chain.later(:1hour, :30minutes);
#
# my $h = '/home/dex/not-there.txt'.IO.&try($*IN).open(:r);
# my $o = '/home/dex/not-there.txt'.IO.&try;
# say $o;
# dd $h;
#
# my \j = (1|2|3);
#
# dd j.&pry.WHY;
# .say for j.&pry.eigenstates;
#
# }
#
# class InterceptHOW is Metamodel::ClassHOW {
# method publish_method_cache(|) { }
# }
#
# sub ipry(Mu $the-object is raw) {
# use InterceptAllMethods;
#
# my class Interceptor {
# has Mu $!the-object;
# method ^find_method(Mu \type, Str $name) {
# my method (Mu \SELF:) is raw {
# use nqp;
# my $the-object := nqp::getattr(SELF, Interceptor, '$!the-object');
# nqp::getattr($the-object, $the-object.WHAT, '$!' ~ $name)
# }
# }
# }
#
#
# # my \Interceptor = InterceptHOW.new_type(:name<Interceptor>);
# # Interceptor.^add_attribute(Attribute.new(:name<$!the-object>, :type(Mu), :package(Interceptor)));
# # Interceptor.^add_meta_method('find_method',
# # my method (Mu \type, Str $name) {
# # my method (Mu \SELF:) is raw {
# # use nqp;
# # my $the-object := nqp::getattr(SELF, Interceptor, '$!the-object');
# # nqp::getattr($the-object, $the-object.WHAT, '$!' ~ $name)
# # }
# # });
# # Interceptor.^compose;
#
# use nqp;
# nqp::p6bindattrinvres(nqp::create(Interceptor), Interceptor, '$!the-object', $the-object);
# }
#
# {
# my \j = (1|2|3);
# .say for j.&ipry.eigenstates;
# }
# sub interceptor(Method $the-method){
# use InterceptAllMethods;
# use nqp;
#
# sub (Mu $the-object is raw) {
# my class Interceptor {
# has Mu $!the-object;
# has Code $!the-method;
#
# method ^find_method(Mu \type, Mu:D $name) {
# my method (Mu \SELF: |c) is raw {
# $!the-method.($!the-object, $name, |c)
# }
# }
# method ^introspect(Mu \type, Mu \obj) {
# my method call-it() is raw {
# $!the-object
# }
# obj.&call-it;
# }
# }
#
# nqp::p6bindattrinvres(
# nqp::p6bindattrinvres(nqp::create(Interceptor), Interceptor, '$!the-object', $the-object),
# Interceptor, '$!the-method', $the-method);
# }
# }
#
# my &first-defined = interceptor(
# my method (Positional \SELF: $name) {
# for SELF -> $e {
# dd $e;
# with $e."$name"(|%_) {
# .return
# }
# }
# Nil
# }
# );
# sub true-then($self) {
#
# }
#
# sub defined-then($self) {
#
# }
#
# my $file = <file1.txt file2.txt file3.txt nohup.out>».IO.&first-defined.open(:r);
#
# dd $file;
#
# my &poke = interceptor(my method (Mu \SELF: $name, |c) is rw {
# use nqp;
# Proxy.new(
# FETCH => method () { nqp::getattr_s(SELF, SELF.WHAT, '$!' ~ $name) },
# STORE => method (\v) { nqp::bindattr_s(SELF, SELF.WHAT, '$!' ~ $name, v); v }
# )
# });
#
# {
# my \j = (1|2|3);
# dd j;
# j.&poke.type = 'all';
# dd j;
# }
#
# multi sub methodify(%h) {
# role Undefined { method defined { False } }
# interceptor(
# my method (Mu \SELF: $name, |c) is rw {
# return-rw SELF.AT-KEY($name)
# }
# ).(%h)
# }
#
# my %h = :answer(42);
# my $o = methodify(%h);
# $o.answer.say;
# $o.awesome = <Raku Ruby Rust>;
# say $o.awesome;
# $o."WHAT"() = ‚LOL WUT‽‘;
# dd %h;
multi sub methodify(%h, :$deeply!) {
sub interceptor(%h, $parent = Nil){
use InterceptAllMethods;
use nqp;
class Interceptor {
has Mu $!the-object;
has Mu @!stack;
method ^find_method(Mu \type, Mu:D $name) {
say "looking for $name";
my method (Mu \SELF: |c) is raw {
my @new-stack = @!stack;
@new-stack.push: $name;
my $the-object = $!the-object;
my \nextlevel = SELF.^new($!the-object, @new-stack, $name);
Proxy.new:
FETCH => method FETCH (Mu \s:) {
nextlevel
},
STORE => method STORE (Mu \s: \v) {
$the-object{||@new-stack} = v;
v
}
}
}
method ^introspect(Mu \type, Mu \obj) {
my method call-it() is raw {
$!the-object, @!stack
}
obj.&call-it;
}
method ^new(Mu \type, $the-object!, @new-stack?, $name?) {
$name
?? nqp::p6bindattrinvres(
nqp::p6bindattrinvres(nqp::create(Interceptor), Interceptor, '$!the-object', $the-object),
Interceptor, '@!stack', @new-stack)
!! nqp::p6bindattrinvres(nqp::create(Interceptor), Interceptor, '$!the-object', $the-object)
}
}
Interceptor.^new(%h)
}
interceptor(%h)
}
my %h2;
my $o2 = methodify(%h2, :deeply);
dd $o2.^introspect($o2);
$o2.a.b = 42;
my $b = $o2.a.b;
dd %h2;
$o2.a.b.c = <answer>;
dd %h2;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment