[Grace-core] Inheritance in Javascript version

Kim Bruce kim at cs.pomona.edu
Mon Aug 12 11:18:10 PDT 2013


The following code works in the C-backend, but not in the javascript backend:

class c.new {
    var theWidth := 0
}

class d.new {
    inherits c.new
    method width := (w:Number) -> Done {
        theWidth := w
        print(theWidth)
    }
}

def x = d.new
x.width:= 5

---------------
My understanding was that unlabeled variables were considered confidential.  If not, then how do we label them to be confidential readable or confidential writeable (or both)?

Kim



On Aug 9, 2013, at 6:06 PM, Michael Homer <mwh at ecs.vuw.ac.nz> wrote:

> 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