Objects.borg

Objects.borg


{
` ---------------------------
` -- BLACK MAGIC STARTS HERE
` ---------------------------
setsuper(nxtdct())::
    {
    dct:nxtdct[4];
    super:nxtdct();
    `search till the next frame is a [frame] or [dctname]
    while((text(dct[3,1])!="[frame]") &
          (text(dct[3,1])!="[dctname]") ,dct:=dct[3]);
    `replace the super
    dct[3]:=super;
    super
    };
` ---------------------------
` -- BLACK MAGIC ENDS HERE
` ---------------------------

`point creates a point, by defining all its methods
`in its own environment. Afterwards this environment
`is assigned to self and returned. (the clone()
`operator returs the current environment.
point(x,y)::
    {
    setx(nx)::x:=nx;
    sety(ny)::y:=ny;
    show()::display("point(",x,",",y,")");
    type()::
        {
        display("Hello I'm a ");
        self.show();
        display(eoln)
        };
    self:clone()
    };


`square creates a square, by adopting the behavior
`of a point. This is done by creating a point and
`changing its own environment. Afterwards the self
`of the point is changed to reflect our own behavior
square(x,y,w)::
    {
    superpoint:setsuper(point(x,y));
    setw(nw)::w:=nw;
    show()::
         {
        display("square(",w,") at ");
        superpoint.show()
        };
    self:=clone()
    };

`rect creates a rectangle by adopting the behavior of
`a square. Its behavior is similar to that of
`the square, except that the rectangle uses
`the superpoint instead of the supersquare.
`By doing so we bypass the show behavior
`of the square.
rect(x,y,w,h)::
    {
    supersquare:setsuper(square(x,y,w));
    seth(nh)::h:=nh;
    show()::
        {
        display("rect(",w,":",h,") at ");
        superpoint.show()
        };
    self:=clone()
    };

`cripplerect is an illustration how we can use dynamic
`inheritance. Now we reassign our super behavior to be
`the behavior of parameter p. 'p' should implement the
`behavior 'show'. Changing 'p' from the outside also
`results in changes for this rect.
cripplerect(p,w,h)::
    {
    super:setsuper(p);
    seth(nh)::h:=nh;
    show()::
        {
        display("rect(",w,":",h,") at ");
        super.show()
        };
    self:clone()
    };

` ---------------------------
` -- Demonstration functions
` ---------------------------
inheritance()::
    {
    a:point(10,20);
    b:square(10,20,30);
    c:rect(10,20,30,40);
    a.type();
    b.type();
    c.type();
    a.setx("***");
    b.setw("***");
    c.seth("***");
    a.type();
    b.type();
    c.type()
    };

delegation()::
    {
    a:point("--X--","--Y--");
    b:cripplerect(a,"--W--","--H--");
    `rect b shares point a for its behavior
    a.show(); display(eoln);
    b.show(); display(eoln);
    `changing X in rect, changes also X in point a
    b.setx("--NX--");
    b.seth("--NH--");
    a.show(); display(eoln);
    b.show(); display(eoln);
    `trying to change W (a rect behavior) is impossible !
    `(hence the name cripplerect, its behaviour is incomplete)
    b.setw("--NW--")
    };

display("inheritance()",eoln,"delegation()")
}