#!/usr/local/bin/rune -x # # Demonstrate refinement import "sys"; import ; alias stdio.File *stdout = stdio.stdout; class Fubar { int a = 1; int b = 2; int c = 3; global int d = 4; global int e = 5; method int subme() { return(this.a - this.b); } method int subme2() { return(this.a - this.b); } global method int gsubme() { return(this.d - this.e); } global method int gsubme2() { return(this.d - this.e); } method int addme() { return(this.a + this.b); } method int mulmeagain() { return(this.mulme()); } method int mulme() { return(this.a * this.b + 1); } } subclass Fubar as SubFubar { # NOTE: explicitly not refining (a). # int a = 10; refine int b = 20; refine global int e = 6; refine method int subme() { return(this.a - this.b); } # NOTE: explicitly not refining (subme2). # method int subme2() { return(this.a - this.b); } # gsubme (refined) and gsubme2 (not refined). # # refine global method int gsubme() { return(this.d - this.e); } global method int gsubme2() { return(this.d - this.e); } refine method int mulme() { return(super.mulme() + 1); } } subclass SubFubar as SubSubFubar { # note: explicitly not refining a # refine int b = 5; refine global int e = 7; refine method int subme() { return(this.a - this.b - 4); } refine method int subme2() { return(this.a - this.b - 4); } # gsubme (refined all the way through) and gsubme2 (refined here only). # # refine global method int gsubme() { return(this.d - this.e - 10); } refine global method int gsubme2() { return(this.d - this.e); } } int main(int ac, char **av) { SubFubar fubar; SubSubFubar s2; Fubar @x = &s2; # [g]subme() is refined all the way through so we should get # the subsubclass [g]subme() function. # stdout->show("Should return 1,5:", x->subme(), x->b); stdout->show("Should return -13,5:", x->gsubme(), x->b); stdout->show("Should return -13,5:", s2.gsubme(), s2.b); # [g]subme2() is not refined all the way through so execution via # the superclass will use a replication of the superclass function # and not the overloaded name in either subclass. The subsubclass # is refining the independent [g]subme2() created in the subclass, # not the original in the superclass which was never refined. # stdout->show("Should return -4,5:", x->subme2(), x->b); stdout->show("Should return -3,5:", x->gsubme2(), x->b); # this should return 21 because we have not refined A. # Thus 'addme' in Fubar only sees the original A (it's # overloaded), while anyone accesssing SubFubar directly # will see the new a. # stdout->show("should return 21:", fubar.addme()); # This should return -10. subme() # stdout->show("should return -10:", fubar.subme()); # This should return 10+5+3 = 18 # stdout->show("should return 18:", s2.a + s2.b + s2.c); # This should return 6 (a is 1 relative to Fubar's addme # because we don't refine it), and b is 5. # stdout->show("should return 6:", s2.addme()); stdout->show("should return 1:", s2.subme()); # original a (1) (because the first subclass did not refine it, it is # independant), refined b (5), then the second subclass's mulme(). # Result: ((1 * 5 + 1) + 1) = 7 # stdout->show("should return 7:", s2.mulme()); # mulmeagain() is from the original class. Make sure it uses the # refined mulme(). # stdout->show("should return 7:", s2.mulmeagain()); return(0); }