Introduction
PropObjs External Api (XApi) is an interface for generalizing specialized implementations. If a subclass of PropObj implements a method relating to a general protocol, exposing that method via XApi might be a good idea as it can then be called without the need for casting away from PropObj.
Motivation
The main motivation has been from the need to further separate operations (method calls) and data. Before XApi, the PropObj protocol made it easy for operations to exist within PropDefs (Append PropDefs) through PropObj.get(..):Object
. Implementing these through XApi instead means fewer PropDefs, faster calls, cm-like key collision handling, easier to read code (a more obvious call), a more intentional protocol (fewer potential side effects and simpler), etc...
Example 1
/** * XApi example 1. */ public class XApiExample extends PropObj { /**
* X-API.
*/
public xapi { public int myTestOp(int a); } /**
* My test operation.
*/
extend public int myTestOp(int a) { return a + 1; } } { PropObj ex = XApiExample(); // XApiExample is casted as PropObj. pln(ex.xrun("myTestOp", a=2)); // Able to run methods from
// XApiExample as a PropObj. }
Output:
3
PropObj XApi
xrun
PropObj.xrun(..):Object
is how one calls an XApi definition. These definitions are pre-compiled and cached objects retained per class, not per instance. Therefore, if you were to instantiate another XApiExample
' in the code from Example 1, the XApi definitions would be pre-compiled, appended only the first time xrun()
is called, and only appended/created once for that class type.
/** * Run external api function helper. */ final public Object xrun(str k, props: params) { return xrun(k, params); } /** * Run external api function. */ extend public Object xrun(str k, str->Object params, SrcRef src=#:src) { return xApiManager.run(this, k, params, src); }
xclear
PropObj.xclear():bool
clears the XApi definitions for that class in the manager. It will return true if removed successfully. This is needed in order to force update the XApi definitions in cases where they may have changed. In general, these are fairly static definitions, however, one might need to clear during development.
/** * Clear external api for this class type. * If xrun is called again, api is re-appended. */ final public bool xclear() { return xApiManager.clear(class); }
xdefs
PropObj.xdefs():XApiDefs
is the way to get all class XApi definitions.PropObj.xdefs(k :
str):XApiDef[]
is the way to get all class XApi definitions pertaining to the method name 'k'. These are useful when determining if a PropObj implements an expected definition as well as gathering that definitions required arguments.
/** * Individual external api definitions for key 'k'. */ final public XApiDef[] xdefs(str k) { return xApiManager.get(this, k); } /** * External api definitions. */ final public XApiDefs xdefs() { return xApiManager.get(class); }
Globals
There are a couple of global functions that are handy to know about when developing. The dump function will show all current definitions within the manager and the clear function will clear all XApi defs from the manager (all classes) so that they are re-appended when used again.
/** * Dump external api. */ public void dumpXApiManager() { xApiManager.dump(); } /** * Clear external api. */ public void clearXApiManager() { xApiManager.clear(); }
Example 2
/** * XApi example 2. */ public class XApiExample2 extends PropObj { /** * X-API. */ public xapi { public int myTestOp(int a, int b=3); } /** * My test operation. */ extend public int myTestOp(int a, int b) { return a + b; } } { PropObj ex = XApiExample2(); pln(ex.xrun("myTestOp", a=2)); pln(ex.xrun("myTestOp", a=3, b=10)); }
Output: 5 13
Example 3
/** * X-Api example 3. */ public class XApiExample3 extends PropObj { /** * X-API. */ public xapi { public int myExternalOp(int a, int b=3) = myInternalOp; } /** * My internal operation. */ extend public int myInternalOp(int a, int b) { return a + b; } } { PropObj ex = XApiExample3(); ex.xclear(); pln(ex.xrun("myExternalOp", a=2)); pln(ex.xrun("myExternalOp", a=3, b=10)); pln(ex.xrun("myInternalOp", a=4)); }
Output: 5 13 XApi Error -- XApiDefsKeyError No XApiDefsEntry assosiated with key: myInternalOp c:\CetDev\Main\base\cm\props\propObj.cm(985, 31): XApi Error Src
Comments
0 comments
Please sign in to leave a comment.