[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