[Xotcl] Re: [Xotcl] RE: [Xotcl] Re: [Xotcl] Object mixin with passing init args ?
uwe.zdun@uni-essen.de
uwe.zdun@uni-essen.de
Wed, 13 Dec 2000 11:39:02 +0100 (CET)
>>>>> "ZV" == Zoran Vasiljevic <zoran@munich.com> writes:
ZV> ------Original Message------
ZV> From: <uwe.zdun@uni-essen.de>
ZV> To: Zoran Vasiljevic <zoran@munich.com>
ZV> Sent: December 13, 2000 9:55:56 AM GMT
>> 2. However, in the "mixin" case we could enable argument passing,
>> because "mixin" has just one argument? The rest could be passed > to
ZV> "init". any objections?
ZV> obj mixin Foo arg1 arg2 arg3
ZV> would pass arg1-arg3 to init of Foo. Right?
yes
ZV> obj mixin [list Foo Bar] arg1 arg2 arg3
ZV> would pass arg1-arg3 to init of Foo AND of Bar. Right again?
yes
ZV> Is so, then I think it should be done, if possible. 0.85 ? 0.9 ?
if there are no objections we can include this right now (and
officially in 0.84) ... its just a little change ... Just exchange
the appended XOTclOMixinMethod in xotcl.c and re-compile to test it:
#################################################
Class A
A instproc init args {puts [self class]--$args;next}
Class C
C instproc init args {puts [self class]--$args;next}
Class B
B instproc init args {puts [self class]--$args;next}
B b
# every thing works
puts ++++++++++++++++++++++++++
b mixin A arg1 arg2 arg3
puts ++++++++++++++++++++++++++
b mixin {A C} arg1 arg2
puts ++++++++++++++++++++++++++
b mixin {A C} arg1
puts ++++++++++++++++++++++++++
b mixin {A C}
# but here we have to add the args ... because "mixin"
# is called before "init"
puts ++++++++++++++++++++++++++
B b2 a1 a2 a3 -mixin {A C}
puts ++++++++++++++++++++++++++
B b2 a1 a2 a3 -mixin {A C} a1 a2 a3
#################################################
--Uwe
--
Uwe Zdun
Specification of Software Systems, University of Essen
Phone: +49 201 81 00 332, Fax: +49 201 81 00 398
zdun@xotcl.org, uwe.zdun@uni-essen.de
########################################################################
static int
XOTclOMixinMethod (ClientData cd, Tcl_Interp* in, int objc, Tcl_Obj *objv[]) {
int oc; Tcl_Obj** ov;
XOTclObject* obj = XOTclAsObject(in, cd);
int i, result = TCL_OK;
XOTclClass *mcl=0;
Tcl_ObjCmdProc *mproc = 0;
Command *mProcInfo =0;
ClientData mcp;
int isDestroyed = 0;
if (!obj) return XOTclObjErrType(in, obj->cmdName, "Object");
if (objc < 2)
return XOTclObjErrArgCnt(in, obj->cmdName, "mixin <classes> ?args?");
if (Tcl_ListObjGetElements(in,objv[1], &oc, &ov)!= TCL_OK) return TCL_ERROR;
MixinRemoveList(&obj->mixins);
obj->mixinDefined = XOTCL_MIXINS_INVALID;
for (i = 0; i < oc; i++) {
char* av = ObjStr(ov[i]);
XOTclClass* mixin = XOTclGetClass(in, av);
if (!mixin)
return XOTclErrBadVal(in, "a list of classes", ObjStr(objv[1]));
if (!XOTclIsClass(in, (ClientData) mixin))
return XOTclVarErrMsg(in, "Mixin for ", ObjStr(obj->cmdName),
" must be class, got: ", av, (char*)0);
MixinAdd(in, &obj->mixins, mixin);
}
MixinComputeDefined(in, obj);
/*
* call "init" on the mixin
*/
MixinStackPush(obj);
obj->mixinStack->mixinInit = 1;
obj->mixinStack->mixinChainOn = 1;
mProcInfo = MixinSearchProc(in, obj, "init",
&mcl, &mproc, &mcp);
if (mproc) {
int oc = objc-1;
DEFINE_NEW_TCL_OBJECTS_ON_STACK(oc,ov);
ov[0] = global_objects[INIT];
memcpy(ov+1, objv+2, sizeof(Tcl_Obj *)*(oc-1));
/* set flag to prevent calling a mixin/the class constructor twice */
result = callProcCheck(mcp, in, oc, ov, mProcInfo,
obj, mcl, "init", 0, 1 /*isMixinEntry*/, &isDestroyed);
FREE_TCL_OBJECTS_ON_STACK(ov);
}
if (!isDestroyed && obj->mixinStack)
MixinStackPop(obj);
return result;
}