Index: TODO =================================================================== diff -u -rc417409d8e77b24b3cb2a8966423452295ed68d8 -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- TODO (.../TODO) (revision c417409d8e77b24b3cb2a8966423452295ed68d8) +++ TODO (.../TODO) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -5108,117 +5108,19 @@ Makefile: - fix load paths for sublibs (e.g. mongodb) in regression test +nsf.c: +- added nsf::var::get and "::nx::var get" to provide selector + based interface for variable reading (used in slotmethod get + of nx::VariableSlot) ======================================================================== TODO: - TODO: rename "slotassign" to "slotset"? - TODO: update tutorial and migration guide - why is there no pos/index arg for mixin|filter delete? -- finish nx-property reform +- finish nx-property reform (merge into master) -- -incremental: setting incremental will promote a property/variable - from a non-multivalued one to a multivalued one -> - i.e., it becomes 0..* unconditionally - - if the following is stated (ambiguous, but allowed): - - /obj/ object property -incremental a:1..1 - - we will end up with "a" becoming 0..*, allowing empty strings without - this being acknowledged by the definition (even if ambiguous). maybe this is more compelling when - setting incremental a posteriori and reconfigure a property/variable. - - suggestion: make the lower bound always respected -> 1..1 becomes - 1..*, 0..1 becomes 0..* - - alternatively, we can enforce that -incremental can only be used on - props/vars explicitly declared multivalued, rather than promoting - them silently? - - >>> - Maybe limiting -incremental to props/vars explicitly declared - multivalued would be more honest, simply because 0..1/1..1 permit - values (any Tcl word) which cannot be turned in to a list rep no - way ... so silently attempting to promote them will always have NX - throw up. - -- at this point, the documentation of variable vs. property (in the - man pages and the tutorial) boils down to: - - "property equals variable despite a different default value of - nonpos arg -configurable" (and the consequences entailed by this - condition -> configure option, slot object). - - (agreed, they also differ slightly by their definition syntaxes, - e.g. placement of the default value etc., but this is also more a - historical artifact) - - historically, there used to be more differences (no accessors for - variable etc.), right now, the largest portions of the their - documentation is identical. - - so, I act as the devil's advocate: is it worth keeping both, rather - than giving an example of how to use -configurable on - property to achieve what is now achieved by variable (or vice versa)? - - one could restate anything written in Section 3.1.2 of the tutorial - by substituting occurrences of ":variable" for ":property - -configurable false ...". Or, if the notion of variable should take - precedence (with the sections being named "non-configurable instance variables" - ...) drop property and keep ":variable -configurable false" which - literally expressed what is stated in the section headings. - - or, to be on the safe side, make "property" a requirable feature and - just keep "variable" for the core API? - - maybe I am wrong, if so, what is a convincing statement/scenario - (from the API perspective) to give to the reader of property - vs. variable rather than explaining property vs. property - -configurable false (or variable vs. variable -configurable false) - only? (apparently, i can't think of one) - -- incremental: should we add a third operation? - - /obj/ /prop/ get /index/ - - right now, we only provide a setter facade (add, delete) for list - values, no getter one. Reasons: consistency (per-element getter + - setter), a complete getter+setter facade would also allow for - switching from a list representation of multivalued values to - another one (e.g., some mongodb data structure?) without changing - clients of the incremental interface (e.g., which now use [lindex] - etc. to retrieve elements from the property-managed list value) ... - - get would behave like (=be implemented with) lindex. - - >>> - * the typical idiom for set-valued db-results is foreach, not lindex. - Is there a convincing use case? from databases one gets a "set" of values - accessing the nth one is rather a border case. - * We have for variable and relation slots aleady "assign", "get", - "add" and "delete", so "get" is not reasonable naming choice. - * The slot interface is extensible. different slot methods of choice can be added via - packages. so why bloat the implementation? - - >>> (adding discussion item from yesterday) - - * using the argument arity for the conditional dispatch behind the - incremental interface leads to the situation that "get" cannot - be called directly, other than assign, get, and delete. there is - no warning raised, no feedback given to the client. - * therefore, should we provide for three modes (as an example): - - - implicit slot interface (arity-based conditional dispatch), - allows for refining the slot interface "behind the scenes"- - - explicit slot interface: assign + get are "exported" to - clients = must be used. there is no convenience way of - getting/setting a property/variable (implementation using ensembles). - - incremental slot interface: implies explicit and adds "add" + - "delete" (downside: every client must use the explicit - interface: assign, get, add, delete; upside: no ambiguities - such as with get) - - check deactivated tests in tests/serialize.test C(One), C(IgnoreAll), C(None2) and xlloc fix Index: generic/nsf.c =================================================================== diff -u -rc417409d8e77b24b3cb2a8966423452295ed68d8 -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- generic/nsf.c (.../nsf.c) (revision c417409d8e77b24b3cb2a8966423452295ed68d8) +++ generic/nsf.c (.../nsf.c) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -25775,6 +25775,20 @@ } /* +cmd var::get NsfVarGetCmd { + {-argName "-array" -required 0 -nrargs 0} + {-argName "object" -required 1 -type object} + {-argName "varName" -required 1 -type tclobj} +} +*/ +static int +NsfVarGetCmd(Tcl_Interp *interp, int withArray, + NsfObject *object, Tcl_Obj *varName) { + + return NsfVarSetCmd(interp, withArray, object, varName, NULL); +} + +/* cmd var::import NsfVarImportCmd { {-argName "object" -type object} {-argName "args" -type args} Index: generic/nsfAPI.decls =================================================================== diff -u -r85ee1fdb043ed3f82fd272cc004c476c40861fdb -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- generic/nsfAPI.decls (.../nsfAPI.decls) (revision 85ee1fdb043ed3f82fd272cc004c476c40861fdb) +++ generic/nsfAPI.decls (.../nsfAPI.decls) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -241,6 +241,12 @@ {-argName "object" -required 1 -type object} {-argName "varName" -required 1} } {-nxdoc 1} +cmd "var::get" NsfVarGetCmd { + {-argName "-array" -required 0 -nrargs 0} + {-argName "object" -required 1 -type object} + {-argName "varName" -required 1 -type tclobj} +} {-nxdoc 1} + cmd "var::import" NsfVarImportCmd { {-argName "object" -required 1 -type object} {-argName "args" -type args} Index: generic/nsfAPI.h =================================================================== diff -u -r85ee1fdb043ed3f82fd272cc004c476c40861fdb -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- generic/nsfAPI.h (.../nsfAPI.h) (revision 85ee1fdb043ed3f82fd272cc004c476c40861fdb) +++ generic/nsfAPI.h (.../nsfAPI.h) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -281,7 +281,7 @@ /* just to define the symbol */ -static Nsf_methodDefinition method_definitions[106]; +static Nsf_methodDefinition method_definitions[107]; static CONST char *method_command_namespace_names[] = { "::nsf::methods::object::info", @@ -415,6 +415,8 @@ NSF_nonnull(2) NSF_nonnull(4); static int NsfVarExistsCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) NSF_nonnull(2) NSF_nonnull(4); +static int NsfVarGetCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) + NSF_nonnull(2) NSF_nonnull(4); static int NsfVarImportCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) NSF_nonnull(2) NSF_nonnull(4); static int NsfVarSetCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) @@ -626,6 +628,8 @@ NSF_nonnull(1); static int NsfVarExistsCmd(Tcl_Interp *interp, int withArray, NsfObject *object, CONST char *varName) NSF_nonnull(1) NSF_nonnull(3) NSF_nonnull(4); +static int NsfVarGetCmd(Tcl_Interp *interp, int withArray, NsfObject *object, Tcl_Obj *varName) + NSF_nonnull(1) NSF_nonnull(3) NSF_nonnull(4); static int NsfVarImportCmd(Tcl_Interp *interp, NsfObject *object, int nobjc, Tcl_Obj *CONST nobjv[]) NSF_nonnull(1) NSF_nonnull(2); static int NsfVarSetCmd(Tcl_Interp *interp, int withArray, NsfObject *object, Tcl_Obj *varName, Tcl_Obj *value) @@ -775,6 +779,7 @@ NsfShowStackCmdIdx, NsfUnsetUnknownArgsCmdIdx, NsfVarExistsCmdIdx, + NsfVarGetCmdIdx, NsfVarImportCmdIdx, NsfVarSetCmdIdx, NsfVarUnsetCmdIdx, @@ -2179,6 +2184,27 @@ } static int +NsfVarGetCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + ParseContext pc; + (void)clientData; + + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], + method_definitions[NsfVarGetCmdIdx].paramDefs, + method_definitions[NsfVarGetCmdIdx].nrParameters, 0, NSF_ARGPARSE_BUILTIN, + &pc) == TCL_OK)) { + int withArray = (int )PTR2INT(pc.clientData[0]); + NsfObject *object = (NsfObject *)pc.clientData[1]; + Tcl_Obj *varName = (Tcl_Obj *)pc.clientData[2]; + + assert(pc.status == 0); + return NsfVarGetCmd(interp, withArray, object, varName); + + } else { + return TCL_ERROR; + } +} + +static int NsfVarImportCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ParseContext pc; (void)clientData; @@ -3056,7 +3082,7 @@ } } -static Nsf_methodDefinition method_definitions[106] = { +static Nsf_methodDefinition method_definitions[107] = { {"::nsf::methods::class::alloc", NsfCAllocMethodStub, 1, { {"objectName", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Tclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, @@ -3350,6 +3376,11 @@ {"object", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Object, NULL,NULL,"object",NULL,NULL,NULL,NULL,NULL}, {"varName", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_String, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, +{"::nsf::var::get", NsfVarGetCmdStub, 3, { + {"-array", 0, 0, Nsf_ConvertTo_String, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"object", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Object, NULL,NULL,"object",NULL,NULL,NULL,NULL,NULL}, + {"varName", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Tclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +}, {"::nsf::var::import", NsfVarImportCmdStub, 2, { {"object", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Object, NULL,NULL,"object",NULL,NULL,NULL,NULL,NULL}, {"args", 0, 1, ConvertToNothing, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} Index: generic/nsfAPI.nxdocindex =================================================================== diff -u -rccb2c99f6fb6f381dfc7e300584ac08e3d2809d3 -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- generic/nsfAPI.nxdocindex (.../nsfAPI.nxdocindex) (revision ccb2c99f6fb6f381dfc7e300584ac08e3d2809d3) +++ generic/nsfAPI.nxdocindex (.../nsfAPI.nxdocindex) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -39,6 +39,7 @@ set ::nxdoc::include(::nsf::current) 1 set ::nxdoc::include(::nsf::self) 1 set ::nxdoc::include(::nsf::var::exists) 1 +set ::nxdoc::include(::nsf::var::get) 1 set ::nxdoc::include(::nsf::var::import) 1 set ::nxdoc::include(::nsf::var::set) 1 set ::nxdoc::include(::nsf::var::unset) 1 Index: library/mongodb/tests/nsf-mongo.test =================================================================== diff -u -r25023d3c048b369645973fdfa125a3705c7f1898 -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- library/mongodb/tests/nsf-mongo.test (.../nsf-mongo.test) (revision 25023d3c048b369645973fdfa125a3705c7f1898) +++ library/mongodb/tests/nsf-mongo.test (.../nsf-mongo.test) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -5,6 +5,16 @@ # package require nsf + +puts stderr "PWD [pwd]" +puts stderr "auto_path $auto_path" +foreach p [lsort [package names]] { + if {![catch {package present $p}]} { + set l [format %-15s $p] + puts stderr "loaded $l [package ifneeded $p [package require $p]]" + } +} + package require nx::test package require nsf::mongo Index: library/nx/nx.tcl =================================================================== diff -u -r386420862057241aeeaa8034670634b0da02378b -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- library/nx/nx.tcl (.../nx.tcl) (revision 386420862057241aeeaa8034670634b0da02378b) +++ library/nx/nx.tcl (.../nx.tcl) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -1211,20 +1211,6 @@ createBootstrapVariableSlots ::nx::Slot { } - # Define method "value" as a slot forwarder to allow for calling - # value-less slot methods like e.g. "get" dispite of the arity-based - # forward dispatcher. - # ::nx::Slot public method value {obj method prop value:optional pos:optional} { - # if {[info exists pos]} { - # ${:manager} $prop $obj ${:name} $value $pos - # } elseif {[info exists value]} { - # ${:manager} $prop $obj ${:name} $value - # } else { - # ${:manager} $prop $obj ${:name} - # } - # } - # TODO REMOVEME - ###################################################################### # configure nx::ObjectParameterSlot ###################################################################### @@ -1841,22 +1827,10 @@ return [string match {*..[n*]} ${:multiplicity}] } - # ::nx::VariableSlot protected method needsForwarder {} { - # # - # # We just forward, when - # # * "set", "get" and "add" are still untouched, or - # # * or incremental is specified - # # - # if {[:info lookup method add] ne "::nsf::classes::nx::VariableSlot::add"} {return 1} - # if {[:info lookup method set] ne "::nsf::classes::nx::VariableSlot::set"} {return 1} - # if {[:info lookup method get] ne "::nsf::classes::nx::VariableSlot::get"} {return 1} - # if {[info exists :settername]} {return 1} - # if {!${:incremental}} {return 0} - # #puts stderr "[self] ismultivalued" - # return 1 - # } - - # TODO: check detailed xotcl2 implications + # + # When there are accessors defined, we use always the forwarders in + # NX. XOTcl2 has a detailed optimization. + # ::nx::VariableSlot protected method needsForwarder {} { return 1 } @@ -2070,7 +2044,7 @@ # - delete ###################################################################### - ::nsf::method::alias ::nx::VariableSlot value=get ::nsf::var::set + ::nsf::method::alias ::nx::VariableSlot value=get ::nsf::var::get ::nsf::method::alias ::nx::VariableSlot value=set ::nsf::var::set ::nx::VariableSlot public method value=unset {obj prop} { @@ -2709,6 +2683,7 @@ # Object create ::nx::var { :public object alias exists ::nsf::var::exists + :public object alias get ::nsf::var::get :public object alias import ::nsf::var::import :public object alias set ::nsf::var::set } Index: tests/accessor.test =================================================================== diff -u -r0aeccfecef90977dbe8f105c4e808f7f5313486f -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- tests/accessor.test (.../accessor.test) (revision 0aeccfecef90977dbe8f105c4e808f7f5313486f) +++ tests/accessor.test (.../accessor.test) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -55,7 +55,7 @@ ? {c1 cget -p3a} 3 ? {c1 p3a get} 3 ? {c1 configure -p3a 3} "" - ? {c1 p3a get 3} 3 + ? {c1 p3a get 3} {invalid argument '3', maybe too many arguments; should be "value=get ?-array? /object/ /varName/"} ? {c1 p3a set 3} 3 ? {c1 p3a unset} "" ? {c1 cget -p3a} {can't read "p3a": no such variable} Index: tests/alias.test =================================================================== diff -u -rdd169437c7a701da0063a40978614e6148d71221 -r6ad766595b0095a72fb7b3a1d6d34960a013b464 --- tests/alias.test (.../alias.test) (revision dd169437c7a701da0063a40978614e6148d71221) +++ tests/alias.test (.../alias.test) (revision 6ad766595b0095a72fb7b3a1d6d34960a013b464) @@ -11,7 +11,7 @@ # The system methods of nx::VariableSlot are either alias or forwarders ? {lsort [::nx::VariableSlot info methods -type alias]} {value=get value=set} ? {::nx::VariableSlot info method definition value=get} \ - "::nx::VariableSlot public alias value=get ::nsf::var::set" + "::nx::VariableSlot public alias value=get ::nsf::var::get" # define an alias and retrieve its definition set cmd "::nx::Object public alias set ::set"