[Grace-core] Inheritance in Javascript version
Michael Homer
mwh at ecs.vuw.ac.nz
Fri Aug 9 18:06:51 PDT 2013
On Sat, Aug 10, 2013 at 12:42 PM, Kim Bruce <kim at cs.pomona.edu> wrote:
> Hi,
>
> We seem to have a serious problem with inheritance in the Javadraw version of Grace. It appears that to access an inherited feature in a class, you must prefix it be self. Worse luck, when you are using a method inherited in a subclass, and then call it externally, then it doesn't find the correct method.
>
> The following code works fine in the C version of the compiler, but breaks twice in Javascript (note that it uses the objectdraw library in directory Objectdraw2013 in the main repository.
>
> // BoxBall
> import "objectdraw" as od
> import "random" as rand
>
> // Application that plays boxball game
> def BoxBall:od.GraphicApplication = object {
> inherits od.aGraphicApplication.size(500,600)
>
> def boxStartPosn:od.Location = od.aLocation.at(50,80)
> def theBox: od.Resizable2DObject =
> od.aFilledRect.at(boxStartPosn)size(40,40)on(canvas)
>
> theBox.width:=70 // <<<====== Line 13
>
> // required to pop up window and start graphics
> self.startGraphics
>
> }
>
> ==================================
> The first error message in the javascript version is that it does not recognize "canvas". This is fixed by replacing it by "self.canvas". Canvas is a (readable) variable in the superclass, and hence should be accessible without using "self".
It is:
class A.new {
def canvas is readable = 5
}
class B.new {
inherits A.new
method x { print(canvas) }
}
B.new.x
=> 5
Or even:
test:
class A.new {
def canvas is readable = 5
}
main:
import "test" as od
class B.new {
inherits od.A.new
print(canvas)
}
B.new
=> 5
> Even more troubling is that with this fix, the program breaks at runtime at the line:
> theBox.width := 70
>
> The error message is:
> "Error around line 674: RuntimeError: No such method 'theWidth:=' on Object. Did you mean the local theWidth:=? It is not annotated readable.
> From call to Object.width:= at line 13"
> Line 674 of objectdraw is the marked line below:
>
> // abstract class to be extended for 2 dimensional objects that can be
> // resized.
> class aResizable2D.at(location':Location)size(width':Number,height':Number)
> on(canvas':Canvas) -> Resizable2DObject{
> inherits aDrawable2D.at(location')size(width',height')on(canvas')
>
> method width:=(w:Number){
> theWidth := w // <<<===== line 674
> setStateChanged
> }
> ..........
>
> ====
> The class aFilledRect (which generates theBox) inherits from this class:
>
> class aFilledRect.at(location':Location)size(width':Number,height':Number)
> on(canvas':Canvas) -> Resizable2DObject{
> inherits aResizable2D.at(location')size(width',height')on(canvas')
>
> It does NOT override method width:=
>
> Unfortunately this is catastrophic error as it means I cannot use Jameson's animator module to write the demo and lab programs for my course. I would be grateful if someone could take a look at this.
Again, it seems to work if I understand your description correctly:
class A.new {
var theWidth := 0
method width { theWidth }
method width:=(n) { theWidth := n }
}
class B.new {
inherits A.new
method x {
width := 5
}
}
def b = B.new
b.x
print(b.width) // => 5
b.width := 10
print(b.width) // => 10
If you can come up with a test case that fails I will look at it, but
at the moment I can't make any of these behaviours occur.
-Michael
More information about the Grace-core
mailing list