[Oberon] Protocols (interfaces) in Oberon-2

Jörg joerg.straube at iaeth.ch
Mon Oct 26 07:55:02 CET 2020


Chuck

        > Andreas, in your scheme can you create separate protocols, for example
        > "Jsonify" with the method ToJSON and a different protocol "Persistify" with
        > the methods "Store" and "Load", and have other records implement one or the
        > other or neither or both?

Here my proposal for doing this in standard Oberon-07.
In the previous mail, I separated interface/protocol and implementation for clarity. The same should be done here. For brevity, I combined the two here.

MODULE Data;
(* Definition of whatever your internal data structure looks like. Here just an example *)
TYPE
  Tree* = POINTER TO TreeDesc;
  TreeDesc* = RECORD val*: ARRAY 15 OF CHAR; left*, right*: Tree END
END Data.

MODULE Jsonify;
IMPORT Data;
TYPE
  Methods* = POINTER TO MDesc;
  MDesc* = RECORD
    toJSON: PROCEDURE(this: Data.Tree);
  END;
  (* empty or default implementation *)
  PROCEDURE J(this: Data.Tree); END J;
  PROCEDURE New*(VAR m: Method); BEGIN NEW(m); m.toJSON := J END;
END Jsonify.

MODULE Persistify;
IMPORT Data;
TYPE
  Methods* = POINTER TO MDesc;
  MDesc* = RECORD
    Load: PROCEDURE(VAR this: Data.Tree);
    Store: PROCEDURE(this: Data.Tree)
  END;
  (* empty or default implementation *)
  PROCEDURE L(VAR this: Data.Tree); BEGIN this := NIL END L;
  PROCEDURE S(this: Data.Tree); END S;
  PROCEDURE New*(VAR m: Methods); BEGIN NEW(m); m.Load := L; m.Store := S END Init;
END Persistify.

Here now a module using both interfaces/protocols and overwrite even one persist procedure with an own version, if wanted. 
MODULE Usage;
IMPORT Data, Jsonify, Persistify;
TYPE
  User = RECORD (Data.Tree)
    j: Jsonify;
    p: Persistify
  END;
VAR u: User;
PROCEDURE myLoad(this: Data.Tree); (* implement your version of persist Load *) END myLoad;
PROCEDURE New*(VAR u: User);
  BEGIN NEW(u); Jsonify.New(u.j); Persistify.New(u.p); u.p.Load := myLoad END New;

BEGIN
  New(u); u.j.toJSON(u); u.p.Load(u) (* this calls my version *)
END Usage.

Adding the qualifiers "j" and "p" circumvents the ambiguity in case the two interfaces defined methods with the same name.

br
Jörg





More information about the Oberon mailing list