Skip to content

Instantly share code, notes, and snippets.

@ashgti
Created October 1, 2010 16:18
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 ashgti/606426 to your computer and use it in GitHub Desktop.
Save ashgti/606426 to your computer and use it in GitHub Desktop.
my %A = { isa => "A" };
%A<new> = sub {
my %r;
%r<prototype> := %A;
%r<x> = 5;
return %r;
};
%A<foo> = sub ($this) {
my $class = dispatch($this, 'isa');
return "{$class}::foo {$this<x>}";
};
sub dispatch(%obj, $call, *@a, *%b) {
my %ref = %obj;
loop {
if %ref{~$call} {
return %ref{~$call}(%obj, |@a, |%b) if %ref{~$call} ~~ Callable;
return %ref{~$call};
}
if %ref<prototype> {
%ref = %ref<prototype>;
}
else {
die 'failed'
}
}
}
my %a = %A<new>();
say dispatch(%a, 'foo');
my %B = { isa => 'B' };
%B<prototype> := %A;
%B<new> = sub {
my %r;
%r<prototype> := %B;
%r<x> = 1;
return %r;
}
my %b = %B<new>();
say dispatch(%b, 'foo');
protoclass A {
has $x = 5;
}
A.^prototype('foo', method {
return self.WHAT ~ "::foo " ~ self.x;
});
protoclass B is A {
has $x = 1;
}
my $a = A.new;
say $a.foo; #=> "A::foo 5"
my $b = B.new;
say $b.foo; #=> "B::foo 1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment