Index: TODO =================================================================== diff -u -ra3f0f32e8b09815485eb72513da29895c55c0c20 -r5c255e27038ce407b8bdf4706a9942c10da1a940 --- TODO (.../TODO) (revision a3f0f32e8b09815485eb72513da29895c55c0c20) +++ TODO (.../TODO) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) @@ -1971,7 +1971,7 @@ - Extended regression test - make handling of redefinitions in system methods more robust -- follow Tcl nameing convention (uppercase functions) +- follow Tcl naming convention (uppercase functions) - Don't allow to call objects as methods (for the time being) via absolute names. Otherwise, in line {2} below, ::State is @@ -1981,7 +1981,7 @@ {2} Class ::State -parameter x - Converted migration guide to asciidoc -- Overhaul of serveral sections in asciidoc +- Overhaul of several sections in asciidoc - Developed styles for nx for migration guide (.css and source-highlight) - fixed bug in xotcl 2.0 "info forward" @@ -1995,8 +1995,8 @@ - xotcl2.tcl: cleanup of forward implementation - xotcl2.tcl: provide debug version of default init method -- nsf.c: aquire parameter structure for returns more lazyly - (otherwise, a serializer handling returns would aquire the +- nsf.c: acquire parameter structure for returns more lazily + (otherwise, a serializer handling returns would acquire the structure for every argument) - extend regression test @@ -2038,13 +2038,13 @@ - further cleanup of error procs: eliminated NsfObjErrArgCnt() - improve error message, when too many arguments are passed -- extended und overworked mirgration guide (added e.g. multiplicity) +- extended und overworked migration guide (added e.g. multiplicity) - extended regression test - added returns handling for nx in serializer - extended regression test -- provide warning if nonpositional argument is passed more than once +- provide warning if non-positional argument is passed more than once - made error messages more consistent - improved error messages for "returns" and "nsf::is" (omit parameter name) @@ -2066,7 +2066,7 @@ - use tcl parametersyntax for short description of commands/methods - deal with interally-called methods (can be overloaded by the application) - * user-called and interanlly called (e.g. from "create" or "new") + * user-called and internally called (e.g. from "create" or "new") XO_c_create_idx, XO_o_destroy_idx, XO_o_move_idx, * not documented yet: XO_c_requireobject_idx, XO_o_defaultmethod_idx, XO_o_init_idx, @@ -2134,7 +2134,7 @@ for procs) and allows the same introspection interface (info method parameter|parametersyntax, ...) -- removed unneded functions: NsfComputePrecedence(), NsfComputeDependents(), +- removed unneeded functions: NsfComputePrecedence(), NsfComputeDependents(), Nsf_SetVar2Ex(), NsfOSetInstVar(), Nsf_ObjGetVar2(), NsfOGetInstVar(), qNsfCreateObject() - removed unneeded external declarations: NsfClassListAdd() NsfClassListFree() @@ -2261,7 +2261,7 @@ - nx.tcl: * full rewrite of slot machinerie, much simpler structure - * relation handling via parameter aliases instread of pseudo converter + * relation handling via parameter aliases instead of pseudo converter * mixinclass SlotOptimizer removed * new class BootStrapAttributeSlot @@ -2411,7 +2411,7 @@ * --enable-dtrace sets DTRACE_OBJ on mac os x empty (since not needed for mac os x dtrace) * added "nsf::configure dtrace on|off" for skipping package initialization (to be handled in D script) - * make compliation clean + * make compilation clean * extended README file * handle self->tracing in D scripts (and in dtrace/sample.tcl, tests/object-system.tcl) * add probes for object creation and freeing @@ -2468,15 +2468,15 @@ * removed methods ::nx::Class.alloc and ::nx::Class.dealloc from predefined method-set - * added defintions such that these methods can be loaded via + * added definitions such that these methods can be loaded via ::nsf::method::require ::nx::Class alloc ::nsf::method::require ::nx::Class dealloc * make explicit that "method ... require" returns a method-handle * removed misleading reference in error message, when a class-spefic method was called on an object; solution is somewhat dangerous for - potentially unknwon client data + potentially unknown client data * added regression tests @@ -2485,7 +2485,7 @@ ::nx::Object.configure from predefined method-set - * added defintions such that these methods can be loaded via + * added definitions such that these methods can be loaded via ::nsf::method::require ::nx::Class recreate ::nsf::method::require ::nx::Object configure @@ -2506,11 +2506,11 @@ * provided default system methods for "init", "defaultmethod" and "unknown" * provided handles for system methods "alloc", "dealloc", "recreate", and "defaultmethod" -* strip in dispatch invocations of "unknown" potental leading colons +* strip in dispatch invocations of "unknown" potential leading colons * removed c-level implementation of init again, since scripted one can be used now as well in registration of createobjectsystem * reduced verbosity -* added defintions such that these methods can be loaded via +* added definitions such that these methods can be loaded via ::nsf::method::require ::nx::Object unknown * added methods ::nsf::methods::object::class and @@ -2531,7 +2531,7 @@ one has to use "o configure -class NEWCLASS". The term "object-class" looks alien to language beginners, the term "class" is much more straightforward. Changing classes - or superclasses is seldomly used by typicall application programs. + or superclasses is seldomly used by typical application programs. For already existing nx scripts, changing "object-class" into class should be straightforward. @@ -2551,7 +2551,7 @@ * The newest trunk version of Tcl in fossil has TclStackFree() and TclStackAlloc() removed We had to substitute this functions. Unfortunately, the lifetime of the strack structures has - changed, so we had shuffle some interals around. + changed, so we had shuffle some internals around. - nsf.c: remove unnecessary test when compiled without NRE - nsf.c: make sure, validCscPtr is always initialized @@ -2613,7 +2613,7 @@ * added two new example files example-nx-reference-many.tcl and example-nx-reference-one.tcl * replaced "arg" by "type" in spec for mongo attributes to make - spec less stange + spec less strange - nsf.c: made potentially unknown clientData more safe (error message, when something is passed via clientData to a method expecting @@ -2638,7 +2638,7 @@ * make Test parameter count 1 the default, change to higher numbers where needed - nsfmongo.c: - * upgrade to newest c-driver (verison 0.3) from git. + * upgrade to newest c-driver (version 0.3) from git. * support connection to replica sets * support attribute selection lists for ::mongo::query (positive and negative selection) @@ -2679,7 +2679,7 @@ * new generalized error message: NsfNoCurrentObjectError() - nx.tcl: replace loops ::nsf::methods::[object|class]::* - by explict command registrations + by explicit command registrations - nsf.c: * added NsfClassListNoDup() to allow just single inserts @@ -2741,20 +2741,27 @@ "info parameter name", and "info parameter syntax" * extended regression test +-nsf.c: + + * Added argument "-reg-object" to ::nsf::method::create to + distinguish between a registration and a definition object for + ensemble methods, similar as on other places. If no reg-object is + provided, it is the same as the definition object. One should + take care that the registration objects are deleted after the + definition objects, which is the case for the usages of the + reg-objects in nx/xotcl. + * The namespaces within plain scripted methods and scripted + ensemble objects are now the same. + * Extended regression test + + TODO: - missing in c-based "info slots": * handle object specific "info slots" * regression tests (eg. "$cls class info slots" vs. "$cls info slots", "-closure") * "info slots", "info parameter" is not in the migration guide -- TODO: why do we have to use ::info in the "info" ensemble? - see nx.tcl - :method "info lookup slots" {{-type ::nx::Slot} -source pattern:optional} { - set cmd [list ::nsf::methods::object::info::lookupslots -type $type] - ... - } - - MixinComputeOrderFullList() could receive a flag to store source classes in checkList - if the check on eg. info-heritage-circular in test/info.method.tcl @@ -2894,6 +2901,8 @@ * org. tutorial (bzw teile davon) ala book or wiki (features als kategorien|tags|sections|directories) + + Ein paar Punkte im folgenden könnten obsolet sein: TODO "Kleinigkeiten" Index: generic/gentclAPI.decls =================================================================== diff -u -r5f856ff709f400d155ff730f532f646db5feef04 -r5c255e27038ce407b8bdf4706a9942c10da1a940 --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 5f856ff709f400d155ff730f532f646db5feef04) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) @@ -75,6 +75,7 @@ {-argName "object" -required 1 -type object} {-argName "-inner-namespace"} {-argName "-per-object"} + {-argName "-reg-object" -required 0 -nrargs 1 -type object} {-argName "methodName" -required 1 -type tclobj} {-argName "arguments" -required 1 -type tclobj} {-argName "body" -required 1 -type tclobj} Index: generic/nsf.c =================================================================== diff -u -r5f856ff709f400d155ff730f532f646db5feef04 -r5c255e27038ce407b8bdf4706a9942c10da1a940 --- generic/nsf.c (.../nsf.c) (revision 5f856ff709f400d155ff730f532f646db5feef04) +++ generic/nsf.c (.../nsf.c) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) @@ -1391,7 +1391,7 @@ return classList; } -#if 1 +#if 0 /* debugging purposes only */ static void NsfClassListPrint(CONST char *title, NsfClasses *clsList) { @@ -4480,7 +4480,7 @@ NsfCommandRelease(del); } -#if 1 +#if 0 /** for debug purposes only */ static void CmdListPrint(Tcl_Interp *interp, CONST char *title, NsfCmdList *cmdList) { @@ -9647,16 +9647,17 @@ static int MakeProc(Tcl_Namespace *nsPtr, NsfAssertionStore *aStore, Tcl_Interp *interp, Tcl_Obj *nameObj, Tcl_Obj *args, Tcl_Obj *body, Tcl_Obj *precondition, - Tcl_Obj *postcondition, NsfObject *object, - int withPer_object, int clsns) { + Tcl_Obj *postcondition, NsfObject *defObject, NsfObject *regObject, + int withPer_object, int withInner_namespace) { Tcl_CallFrame frame, *framePtr = &frame; CONST char *methodName = ObjStr(nameObj); NsfParsedParam parsedParam; Tcl_Obj *ov[4]; int result; + if (regObject == NULL) {regObject = defObject;} /* Check, if we are allowed to redefine the method */ - result = CanRedefineCmd(interp, nsPtr, object, methodName); + result = CanRedefineCmd(interp, nsPtr, defObject, methodName); if (result == TCL_OK) { /* Yes, so obtain an method parameter definitions */ result = ParamDefsParse(interp, nameObj, args, NSF_DISALLOWED_ARG_METHOD_PARAMETER, &parsedParam); @@ -9696,26 +9697,28 @@ Proc *procPtr = FindProcMethod(nsPtr, methodName); if (procPtr) { /* modify the cmd of the proc to set the current namespace for the body */ - if (clsns) { + if (withInner_namespace) { /* * Set the namespace of the method as inside of the class */ - if (!object->nsPtr) { - MakeObjNamespace(interp, object); + if (!regObject->nsPtr) { + MakeObjNamespace(interp, regObject); } - /*fprintf(stderr, "obj %s\n", ObjectName(object)); - fprintf(stderr, "ns %p object->ns %p\n", ns, object->nsPtr); - fprintf(stderr, "ns %s object->ns %s\n", ns->fullName, object->nsPtr->fullName);*/ - procPtr->cmdPtr->nsPtr = (Namespace*) object->nsPtr; + /*fprintf(stderr, "obj %s\n", ObjectName(defObject)); + fprintf(stderr, "ns %p defObject->ns %p\n", nsPtr, defObject->nsPtr); + fprintf(stderr, "ns %s defObject->ns %s\n", nsPtr->fullName, defObject->nsPtr->fullName); + fprintf(stderr, "old %s\n", procPtr->cmdPtr->nsPtr->fullName);*/ + procPtr->cmdPtr->nsPtr = (Namespace *)regObject->nsPtr; } else { /* - * Set the namespace of the method to the same namespace the class has - */ - procPtr->cmdPtr->nsPtr = ((Command *)object->id)->nsPtr; + * Set the namespace of the method to the same namespace the cmd of + * the defObject has. + */ + procPtr->cmdPtr->nsPtr = ((Command *)regObject->id)->nsPtr; } ParamDefsStore((Tcl_Command)procPtr->cmdPtr, parsedParam.paramDefs); - Tcl_SetObjResult(interp, MethodHandleObj(object, withPer_object, methodName)); + Tcl_SetObjResult(interp, MethodHandleObj(defObject, withPer_object, methodName)); result = TCL_OK; } } @@ -9736,10 +9739,10 @@ } static int -MakeMethod(Tcl_Interp *interp, NsfObject *object, NsfClass *cl, Tcl_Obj *nameObj, - Tcl_Obj *args, Tcl_Obj *body, +MakeMethod(Tcl_Interp *interp, NsfObject *defObject, NsfObject *regObject, + NsfClass *cl, Tcl_Obj *nameObj, Tcl_Obj *args, Tcl_Obj *body, Tcl_Obj *precondition, Tcl_Obj *postcondition, - int clsns) { + int withInner_namespace) { CONST char *argsStr = ObjStr(args), *bodyStr = ObjStr(body), *nameStr = ObjStr(nameObj); int result; @@ -9761,7 +9764,7 @@ */ result = cl ? NsfRemoveClassMethod(interp, (Nsf_Class *)cl, nameStr) : - NsfRemoveObjectMethod(interp, (Nsf_Object *)object, nameStr); + NsfRemoveObjectMethod(interp, (Nsf_Object *)defObject, nameStr); } else { /* fprintf(stderr, "don't delete method %s during shutdown\n", nameStr); */ result = TCL_OK; @@ -9778,20 +9781,20 @@ } aStore = opt->assertions; } else { - NsfObjectOpt *opt = NsfRequireObjectOpt(object); + NsfObjectOpt *opt = NsfRequireObjectOpt(defObject); if (!opt->assertions) { opt->assertions = AssertionCreateStore(); } aStore = opt->assertions; } } - result = MakeProc(cl ? cl->nsPtr : object->nsPtr, aStore, + result = MakeProc(cl ? cl->nsPtr : defObject->nsPtr, aStore, interp, nameObj, args, body, precondition, postcondition, - object, cl == NULL, clsns); + defObject, regObject, cl == NULL, withInner_namespace); #else - result = MakeProc(cl ? cl->nsPtr : object->nsPtr, NULL, + result = MakeProc(cl ? cl->nsPtr : defObject->nsPtr, NULL, interp, nameObj, args, body, NULL, NULL, - object, cl == NULL, clsns); + defObject, regObject, cl == NULL, withInner_namespace); #endif } @@ -9800,7 +9803,7 @@ FilterInvalidateObjOrders(interp, cl); } else { /* could be a filter => recompute filter order */ - FilterComputeDefined(interp, object); + FilterComputeDefined(interp, defObject); } return result; @@ -15917,6 +15920,7 @@ {-argName "object" -required 1 -type object} {-argName "-inner-namespace"} {-argName "-per-object"} + {-argName "-reg-object" -required 0 -nrargs 1 -type object} {-argName "name" -required 1 -type tclobj} {-argName "arguments" -required 1 -type tclobj} {-argName "body" -required 1 -type tclobj} @@ -15925,18 +15929,19 @@ } */ static int -NsfMethodCreateCmd(Tcl_Interp *interp, NsfObject *object, - int withInner_namespace, int withPer_object, +NsfMethodCreateCmd(Tcl_Interp *interp, NsfObject *defObject, + int withInner_namespace, int withPer_object, NsfObject *regObject, Tcl_Obj *nameObj, Tcl_Obj *arguments, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition) { NsfClass *cl = - (withPer_object || ! NsfObjectIsClass(object)) ? - NULL : (NsfClass *)object; + (withPer_object || ! NsfObjectIsClass(defObject)) ? + NULL : (NsfClass *)defObject; if (cl == 0) { - RequireObjNamespace(interp, object); + RequireObjNamespace(interp, defObject); } - return MakeMethod(interp, object, cl, nameObj, arguments, body, + return MakeMethod(interp, defObject, regObject, cl, + nameObj, arguments, body, withPrecondition, withPostcondition, withInner_namespace); } @@ -15951,7 +15956,7 @@ static int NsfMethodDeleteCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, Tcl_Obj *methodNameObj) { - return NsfMethodCreateCmd(interp, object, 0, withPer_object, methodNameObj, + return NsfMethodCreateCmd(interp, object, 0, withPer_object, NULL, methodNameObj, NsfGlobalObjs[NSF_EMPTY], NsfGlobalObjs[NSF_EMPTY], NULL, NULL); } @@ -19421,7 +19426,7 @@ } else { NsfClassListAdd(&precedenceList, class, NULL); } - //NsfClassListPrint("precedence", precedenceList); + /* NsfClassListPrint("precedence", precedenceList);*/ if (withSource == 0) {withSource = 1;} slotObjects = ComputeSlotObjects(interp, precedenceList, withSource, type, pattern); Index: generic/tclAPI.h =================================================================== diff -u -r5f856ff709f400d155ff730f532f646db5feef04 -r5c255e27038ce407b8bdf4706a9942c10da1a940 --- generic/tclAPI.h (.../tclAPI.h) (revision 5f856ff709f400d155ff730f532f646db5feef04) +++ generic/tclAPI.h (.../tclAPI.h) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) @@ -325,7 +325,7 @@ static int NsfInvalidateObjectParameterCmd(Tcl_Interp *interp, NsfClass *class); static int NsfIsCmd(Tcl_Interp *interp, int withComplain, Tcl_Obj *constraint, Tcl_Obj *value); static int NsfIsObjectCmd(Tcl_Interp *interp, Tcl_Obj *value); -static int NsfMethodCreateCmd(Tcl_Interp *interp, NsfObject *object, int withInner_namespace, int withPer_object, Tcl_Obj *methodName, Tcl_Obj *arguments, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition); +static int NsfMethodCreateCmd(Tcl_Interp *interp, NsfObject *object, int withInner_namespace, int withPer_object, NsfObject *withReg_object, Tcl_Obj *methodName, Tcl_Obj *arguments, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition); static int NsfMethodDeleteCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, Tcl_Obj *methodName); static int NsfMethodPropertyCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, Tcl_Obj *methodName, int methodproperty, Tcl_Obj *value); static int NsfMyCmd(Tcl_Interp *interp, int withLocal, Tcl_Obj *methodName, int nobjc, Tcl_Obj *CONST nobjv[]); @@ -1282,14 +1282,15 @@ NsfObject *object = (NsfObject *)pc.clientData[0]; int withInner_namespace = (int )PTR2INT(pc.clientData[1]); int withPer_object = (int )PTR2INT(pc.clientData[2]); - Tcl_Obj *methodName = (Tcl_Obj *)pc.clientData[3]; - Tcl_Obj *arguments = (Tcl_Obj *)pc.clientData[4]; - Tcl_Obj *body = (Tcl_Obj *)pc.clientData[5]; - Tcl_Obj *withPrecondition = (Tcl_Obj *)pc.clientData[6]; - Tcl_Obj *withPostcondition = (Tcl_Obj *)pc.clientData[7]; + NsfObject *withReg_object = (NsfObject *)pc.clientData[3]; + Tcl_Obj *methodName = (Tcl_Obj *)pc.clientData[4]; + Tcl_Obj *arguments = (Tcl_Obj *)pc.clientData[5]; + Tcl_Obj *body = (Tcl_Obj *)pc.clientData[6]; + Tcl_Obj *withPrecondition = (Tcl_Obj *)pc.clientData[7]; + Tcl_Obj *withPostcondition = (Tcl_Obj *)pc.clientData[8]; assert(pc.status == 0); - return NsfMethodCreateCmd(interp, object, withInner_namespace, withPer_object, methodName, arguments, body, withPrecondition, withPostcondition); + return NsfMethodCreateCmd(interp, object, withInner_namespace, withPer_object, withReg_object, methodName, arguments, body, withPrecondition, withPostcondition); } } @@ -2395,10 +2396,11 @@ {"::nsf::object::exists", NsfIsObjectCmdStub, 1, { {"value", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, -{"::nsf::method::create", NsfMethodCreateCmdStub, 8, { +{"::nsf::method::create", NsfMethodCreateCmdStub, 9, { {"object", NSF_ARG_REQUIRED, 0, Nsf_ConvertToObject, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-inner-namespace", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-per-object", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-reg-object", 0, 1, Nsf_ConvertToObject, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"methodName", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"arguments", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"body", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, Index: library/nx/nx.tcl =================================================================== diff -u -r53e092b1dceccab3bbd0045bd5b14c1ddedaf68d -r5c255e27038ce407b8bdf4706a9942c10da1a940 --- library/nx/nx.tcl (.../nx.tcl) (revision 53e092b1dceccab3bbd0045bd5b14c1ddedaf68d) +++ library/nx/nx.tcl (.../nx.tcl) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) @@ -106,8 +106,10 @@ } { set object [::nsf::self] set methodName $path - if {[string first " " $path]} { + set regObject "" + if {[string first " " $path] > -1} { set methodName [lindex $path end] + set regObject $object foreach w [lrange $path 0 end-1] { #puts stderr "check $object info methods $path @ <$w>" set scope [expr {[::nsf::is class $object] && !${per-object} ? "class" : "object"}] @@ -147,7 +149,7 @@ } #puts stderr "... final object $object method $methodName" } - return [list object $object methodName $methodName] + return [list object $object methodName $methodName regObject $regObject] } ::nsf::method::property Object __resolve_method_path call-protected true @@ -169,10 +171,13 @@ if {[info exists postcondition]} {lappend conditions -postcondition $postcondition} array set "" [:__resolve_method_path $name] #puts "class method $(object).$(methodName) [list $arguments] {...}" - set r [::nsf::method::create $(object) $(methodName) $arguments $body {*}$conditions] + set r [::nsf::method::create $(object) \ + {*}[expr {$(regObject) ne "" ? "-reg-object [list $(regObject)]" : ""}] \ + $(methodName) $arguments $body {*}$conditions] if {$r ne ""} { # the method was not deleted - ::nsf::method::property $(object) $r call-protected [::nsf::dispatch $(object) __default_method_call_protection] + ::nsf::method::property $(object) $r call-protected \ + [::nsf::dispatch $(object) __default_method_call_protection] if {[info exists returns]} {::nsf::method::property $(object) $r returns $returns} } return $r @@ -186,10 +191,14 @@ if {[info exists postcondition]} {lappend conditions -postcondition $postcondition} array set "" [:__resolve_method_path -per-object $name] # puts "object method $(object).$(methodName) [list $arguments] {...}" - set r [::nsf::method::create $(object) -per-object $(methodName) $arguments $body {*}$conditions] + set r [::nsf::method::create $(object) \ + {*}[expr {$(regObject) ne "" ? "-reg-object [list $(regObject)]" : ""}] \ + -per-object \ + $(methodName) $arguments $body {*}$conditions] if {$r ne ""} { # the method was not deleted - ::nsf::method::property $(object) $r call-protected [::nsf::dispatch $(object) __default_method_call_protection] + ::nsf::method::property $(object) $r call-protected \ + [::nsf::dispatch $(object) __default_method_call_protection] if {[info exists returns]} {::nsf::method::property $(object) $r returns $returns} } return $r @@ -471,8 +480,8 @@ :method "info lookup slots" {{-type ::nx::Slot} -source pattern:optional} { set cmd [list ::nsf::methods::object::info::lookupslots -type $type] # TODO: why do we have to use here ::info? - if {[::info exists source]} {lappend cmd -source $source} - if {[::info exists pattern]} {lappend cmd $pattern} + if {[info exists source]} {lappend cmd -source $source} + if {[info exists pattern]} {lappend cmd $pattern} return [::nsf::my {*}$cmd] } :alias "info children" ::nsf::methods::object::info::children @@ -492,7 +501,7 @@ set slotContainer [::nsf::self]::slot if {[::nsf::object::exists $slotContainer]} { set cmd [list ::nsf::methods::object::info::children -type $type] - if {[::info exists pattern]} {lappend cmd $pattern} + if {[info exists pattern]} {lappend cmd $pattern} return [::nsf::my {*}$cmd] } } @@ -539,24 +548,24 @@ :alias "info mixin classes" ::nsf::methods::class::info::mixinclasses :alias "info mixinof" ::nsf::methods::class::info::mixinof :method "info parameter spec" {name:optional} { - if {[::info exists name]} { + if {[info exists name]} { return [::nsf::my ::nsf::methods::class::info::objectparameter parameter $name] } return [:objectparameter] } :method "info parameter list" {name:optional} { set cmd [list ::nsf::my ::nsf::methods::class::info::objectparameter list] - if {[::info exists name]} {lappend cmd $name} + if {[info exists name]} {lappend cmd $name} return [::nsf::my {*}$cmd] } :method "info parameter name" {name:optional} { set cmd [list ::nsf::my ::nsf::methods::class::info::objectparameter name] - if {[::info exists name]} {lappend cmd $name} + if {[info exists name]} {lappend cmd $name} return [::nsf::my {*}$cmd] } :method "info parameter syntax" {name:optional} { set cmd [list ::nsf::my ::nsf::methods::class::info::objectparameter parametersyntax] - if {[::info exists name]} {lappend cmd $name} + if {[info exists name]} {lappend cmd $name} return [::nsf::my {*}$cmd] } :method "info slots" {{-type ::nx::Slot} -closure:switch -source pattern:optional} { Index: tests/methods.test =================================================================== diff -u -re90e59865348906790e496aa960ef57837456e9e -r5c255e27038ce407b8bdf4706a9942c10da1a940 --- tests/methods.test (.../methods.test) (revision e90e59865348906790e496aa960ef57837456e9e) +++ tests/methods.test (.../methods.test) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) @@ -428,4 +428,99 @@ # check, if missing object is still detected ? ::o::x "No current object; x called outside the context of a Next Scripting method" ? self "No current object; command called outside the context of a Next Scripting method" -} \ No newline at end of file +} + + +# +# Test the current namespaces and resolution for +# a) top-level methods +# b) ensemble methods on level 1 +# c) ensemble methods on level 2 +# +nx::Test case scopes { + Object create o1 { + :public method foo {} {return [namespace current]-[namespace which info]} + :public method "info foo" {} {return [namespace current]-[namespace which info]} + :public method "info bar foo" {} {return [namespace current]-[namespace which info]} + } + + ? {o1 foo} "::-::info" + ? {o1 info foo} "::-::info" + ? {o1 info bar foo} "::-::info" + + Class create C { + :public method foo {} {return [namespace current]-[namespace which info]} + :public method "info foo" {} {return [namespace current]-[namespace which info]} + :public method "info bar foo" {} {return [namespace current]-[namespace which info]} + :create c1 + } + + ? {c1 foo} "::-::info" + ? {c1 info foo} "::-::info" + ? {c1 info bar foo} "::-::info" +} + +# +# Test the current namespaces and resolution for methods +# registered on a object in a certain namespace +# a) top-level methods +# b) ensemble methods on level 1 +# c) ensemble methods on level 2 +# +nx::Test case namespaced-scopes { + + namespace eval ::ns { + Object create o1 { + :public method foo {} {return [namespace current]-[namespace which info]} + :public method "info foo" {} {return [namespace current]-[namespace which info]} + :public method "info bar foo" {} {return [namespace current]-[namespace which info]} + } + Class create C { + :public method foo {} {return [namespace current]-[namespace which info]} + :public method "info foo" {} {return [namespace current]-[namespace which info]} + :public method "info bar foo" {} {return [namespace current]-[namespace which info]} + :create c1 + } + } + + ? {ns::o1 foo} "::ns-::info" + ? {ns::o1 info foo} "::ns-::info" + ? {ns::o1 info bar foo} "::ns-::info" + + ? {ns::c1 foo} "::ns-::info" + ? {ns::c1 info foo} "::ns-::info" + ? {ns::c1 info bar foo} "::ns-::info" +} + + +# +# Test the current namespaces and resolution for methods +# registered on a sub object +# a) top-level methods +# b) ensemble methods on level 1 +# c) ensemble methods on level 2 +# +nx::Test case nested-scopes { + Object create o + Object create o::o1 { + :public method foo {} {return [namespace current]-[namespace which info]} + :public method "info foo" {} {return [namespace current]-[namespace which info]} + :public method "info bar foo" {} {return [namespace current]-[namespace which info]} + } + + ? {o::o1 foo} "::o-::info" + ? {o::o1 info foo} "::o-::info" + ? {o::o1 info bar foo} "::o-::info" + + Class create o::C { + :public method foo {} {return [namespace current]-[namespace which info]} + :public method "info foo" {} {return [namespace current]-[namespace which info]} + :public method "info bar foo" {} {return [namespace current]-[namespace which info]} + :create c1 + } + + ? {c1 foo} "::o-::info" + ? {c1 info foo} "::o-::info" + ? {c1 info bar foo} "::o-::info" +} +