Index: Makefile.in =================================================================== diff -u -r85e95479856b97a27083b3a7d3513ee417f1371a -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- Makefile.in (.../Makefile.in) (revision 85e95479856b97a27083b3a7d3513ee417f1371a) +++ Makefile.in (.../Makefile.in) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -387,6 +387,7 @@ $(TCLSH) $(src_test_dir_native)/info-method.tcl -libdir $(PLATFORM_DIR) $(TESTFLAGS) $(TCLSH) $(src_test_dir_native)/parameters.tcl -libdir $(PLATFORM_DIR) $(TESTFLAGS) $(TCLSH) $(src_test_dir_native)/returns.tcl -libdir $(PLATFORM_DIR) $(TESTFLAGS) + $(TCLSH) $(src_test_dir_native)/method-require.tcl -libdir $(PLATFORM_DIR) $(TESTFLAGS) $(TCLSH) $(src_test_dir_native)/interceptor-slot.tcl -libdir $(PLATFORM_DIR) $(TESTFLAGS) $(TCLSH) $(src_test_dir_native)/aliastest.tcl -libdir $(PLATFORM_DIR) $(TESTFLAGS) $(TCLSH) $(src_test_dir_native)/protected.tcl -libdir $(PLATFORM_DIR) $(TESTFLAGS) Index: TODO =================================================================== diff -u -r85e95479856b97a27083b3a7d3513ee417f1371a -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- TODO (.../TODO) (revision 85e95479856b97a27083b3a7d3513ee417f1371a) +++ TODO (.../TODO) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -1035,6 +1035,12 @@ - added regression test for return value checker - upgraded to TEA 3.9 +- nsf: provided scripted support for "require/provide methods" +- nx: new method ":require namespace" ":require method" "require object method" +- added regression test method-require +- removed requireNamespace from nx.tcl (still exists in xotcl) +- replaced "requireNamespace" by "require namespace" in nx regression tests +- updated migration guide TODO: - nameing Index: doc/next-migration.html =================================================================== diff -u -rc4442ee730996637a63fa8280c0b3791f227f031 -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- doc/next-migration.html (.../next-migration.html) (revision c4442ee730996637a63fa8280c0b3791f227f031) +++ doc/next-migration.html (.../next-migration.html) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -1265,7 +1265,19 @@ -

Predefined Methods

+

Other Predefined Methods

+ + + + + + + + +
XOTclNext Scripting Language
obj requireNamespaceobj require namespace
+ + +

Dispatch, Aliases, etc.

Assertions

@@ -1355,6 +1367,6 @@
- Last modified: Mon Aug 16 10:10:20 CEST 2010 + Last modified: Wed Aug 18 13:17:20 CEST 2010 Index: generic/predefined.h =================================================================== diff -u -r5577ecfb071377c5e04f81074e25e2707d2c1400 -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- generic/predefined.h (.../predefined.h) (revision 5577ecfb071377c5e04f81074e25e2707d2c1400) +++ generic/predefined.h (.../predefined.h) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -2,6 +2,26 @@ "namespace eval ::nsf {\n" "namespace export next current\n" "namespace export alias configure finalize interp is my relation\n" +"proc ::nsf::provide_method {require_name definition {script \"\"}} {\n" +"set ::nsf::methodIndex($require_name) [list definition $definition script $script]}\n" +"proc ::nsf::require_method {object name {per_object 0}} {\n" +"set key ::nsf::methodIndex($name)\n" +"if {[info exists $key]} {\n" +"array set \"\" [set $key]\n" +"if {$(script) ne \"\"} {\n" +"eval $(script)}\n" +"if {$per_object} {\n" +"set cmd [linsert $(definition) 1 -per-object]\n" +"eval [linsert $cmd 1 $object]} else {\n" +"eval [linsert $(definition) 1 $object]}} else {\n" +"error \"cannot require method $name for $object, method unknown\"}}\n" +"proc ::nsf::mixin {object args} {\n" +"if {[lindex $args 0] eq \"-per-object\"} {\n" +"set rel \"object-mixin\"\n" +"set args [lrange $args 1 end]} else {\n" +"set rel \"mixin\"}\n" +"set oldSetting [::nsf::relation $object $rel]\n" +"uplevel [list ::nsf::relation $object $rel [linsert $oldSetting end $args]]}\n" "proc ::nsf::infoError msg {\n" "regsub -all \" \" $msg \"\" msg\n" "regsub -all \" \" $msg \"\" msg\n" Index: generic/predefined.tcl =================================================================== diff -u -r5577ecfb071377c5e04f81074e25e2707d2c1400 -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- generic/predefined.tcl (.../predefined.tcl) (revision 5577ecfb071377c5e04f81074e25e2707d2c1400) +++ generic/predefined.tcl (.../predefined.tcl) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -9,6 +9,49 @@ namespace export alias configure finalize interp is my relation # + # support for method provide and method require + # + proc ::nsf::provide_method {require_name definition {script ""}} { + set ::nsf::methodIndex($require_name) [list definition $definition script $script] + } + + proc ::nsf::require_method {object name {per_object 0}} { + set key ::nsf::methodIndex($name) + if {[info exists $key]} { + array set "" [set $key] + if {$(script) ne ""} { + eval $(script) + } + if {$per_object} { + set cmd [linsert $(definition) 1 -per-object] + eval [linsert $cmd 1 $object] + } else { + eval [linsert $(definition) 1 $object] + } + } else { + error "cannot require method $name for $object, method unknown" + } + } + + # + # nsf::mixin + # + # provide a similar interface as for ::nsf::method, ::nsf::alias, ... + # + proc ::nsf::mixin {object args} { + if {[lindex $args 0] eq "-per-object"} { + set rel "object-mixin" + set args [lrange $args 1 end] + } else { + set rel "mixin" + } + set oldSetting [::nsf::relation $object $rel] + # use uplevel to avoid namespace surprises + uplevel [list ::nsf::relation $object $rel [linsert $oldSetting end $args]] + } + + + # # error handler for info # proc ::nsf::infoError msg { Index: library/nx/nx.tcl =================================================================== diff -u -r304c346008d3c471fa9350eb0b18813eec2a4be6 -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- library/nx/nx.tcl (.../nx.tcl) (revision 304c346008d3c471fa9350eb0b18813eec2a4be6) +++ library/nx/nx.tcl (.../nx.tcl) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -37,7 +37,7 @@ # foreach cmd [info command ::nsf::cmd::Object::*] { set cmdName [namespace tail $cmd] - if {$cmdName in [list "exists" "instvar"]} continue + if {$cmdName in [list "exists" "instvar" "requireNamespace"]} continue ::nsf::alias Object $cmdName $cmd } @@ -325,6 +325,25 @@ ::nsf::setter [::nsf::current object] $methodName } + # Add method "require" + # + Object method require {what args} { + switch -- $what { + object { + set what [lindex $args 0] + if {$what eq "method"} { + ::nsf::require_method [::nx::self] [lindex $args 1] 1 + } + } + method { + ::nsf::require_method [::nx::self] [lindex $args 0] 0 + } + namespace { + ::nsf::dispatch [self] ::nsf::cmd::Object::requireNamespace + } + } + } + ######################## # Info definition ######################## @@ -1196,7 +1215,8 @@ } { if {![info exists object]} {set object [::nsf::current object]} if {![::nsf::objectproperty $object object]} {$class create $object} - $object requireNamespace + # reused in XOTcl, no "require" there, so use nsf primitiva + ::nsf::dispatch $object ::nsf::cmd::Object::requireNamespace if {$withnew} { set m [ScopedNew new -volatile \ -container $object -withclass $class] @@ -1290,7 +1310,8 @@ ::nsf::relation $obj object-filter [::nsf::relation $origin object-filter] ::nsf::relation $obj object-mixin [::nsf::relation $origin object-mixin] if {[$origin info hasnamespace]} { - $obj requireNamespace + # reused in XOTcl, no "require" there, so use nsf primitiva + ::nsf::dispatch $obj ::nsf::cmd::Object::requireNamespace } } else { namespace eval $dest {} Index: tests/aliastest.tcl =================================================================== diff -u -r033c63d771af5253b0e94c2a9c1c6a94df40242e -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- tests/aliastest.tcl (.../aliastest.tcl) (revision 033c63d771af5253b0e94c2a9c1c6a94df40242e) +++ tests/aliastest.tcl (.../aliastest.tcl) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -219,7 +219,7 @@ ? {namespace exists ::U} 0 U object method zap args { return [current class]->[current method] } ::nsf::alias ::U -per-object ZAP ::U::zap - U requireNamespace + U require namespace ? {namespace exists ::U} 1 U object method bar args { return [current class]->[current method] } Index: tests/destroytest.tcl =================================================================== diff -u -r9d9ae3c8df6dacbb526362d371ad9b8fa2523673 -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- tests/destroytest.tcl (.../destroytest.tcl) (revision 9d9ae3c8df6dacbb526362d371ad9b8fa2523673) +++ tests/destroytest.tcl (.../destroytest.tcl) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -552,7 +552,7 @@ ? {::nsf::objectproperty ::module::foo object} 1 ? {::nsf::objectproperty ::module class} 1 - Object create ::o { :requireNamespace } + Object create ::o { :require namespace } namespace eval ::o {namespace import ::module::*} ? {::nsf::objectproperty ::o::Foo class} 1 Index: tests/method-require.tcl =================================================================== diff -u --- tests/method-require.tcl (revision 0) +++ tests/method-require.tcl (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -0,0 +1,58 @@ +package require nx; # namespace import -force ::nx::* +package require nx::test + +Test parameter count 10 +Test case method-require { + + # + # A few method-provides + # + # Some provides could be in e.g. nx.tcl, some could be loaded via + # package require. We could as well think about an auto-indexer + # producing these.... + # + + nsf::provide_method append {::nsf::alias append -objscope ::append} + nsf::provide_method lappend {::nsf::alias lappend -objscope ::lappend} + nsf::provide_method set {::nsf::alias set -objscope ::set} + nsf::provide_method tcl::set {::nsf::alias set -objscope ::set} + nsf::provide_method exists {::nsf::alias exists ::nsf::cmd::Object::exists} + nsf::provide_method foo {::nsf::method foo {x y} {return x=$x,y=$y}} + nsf::provide_method x {::nsf::mixin ::MIX} { + # here could be as well a package require, etc. + ::nx::Class create ::MIX {:method x {} {return x}} + } + + # + # Lets try it out: + # + + nx::Class create C { + :require method set + :require method exists + + # required names can be different from registered names; if there + # are multiple set methods, we could point to the right one + :require method tcl::set + + # object methods: + :require object method lappend + + # a scripted method + :require object method foo + + :require object method x + + # looks as well ok: + :require namespace + } + + C create c1 + ? {c1 set x 100} 100 + ? {c1 exists x} 1 + ? {C lappend some_list e1 e2} "e1 e2" + ? {C foo 1 2} x=1,y=2 + ? {C x} x +} + + Index: tests/varresolutiontest.tcl =================================================================== diff -u -rf3cb5afe6aa1b6761b4a9909058f64ff7d64ab92 -r15d57478e3976d747741fd3df9bcb6ecccc7076d --- tests/varresolutiontest.tcl (.../varresolutiontest.tcl) (revision f3cb5afe6aa1b6761b4a9909058f64ff7d64ab92) +++ tests/varresolutiontest.tcl (.../varresolutiontest.tcl) (revision 15d57478e3976d747741fd3df9bcb6ecccc7076d) @@ -19,7 +19,7 @@ Test case globals set ::globalVar 1 Object create o -o requireNamespace +o require namespace ? {o info vars} "" ? {info exists ::globalVar} 1 ? {set ::globalVar} 1 @@ -45,7 +45,7 @@ o objeval { # require an namespace within an objscoped frame; it is necessary to replace # vartables on the stack - :requireNamespace + :require namespace global g ::nsf::importvar o2 i set x 1 @@ -103,7 +103,7 @@ Object create o2 {set :i 1} Object create o { - :requireNamespace + :require namespace global g ::nsf::importvar o2 i set x 1 @@ -161,7 +161,7 @@ Test case namespaces Object create o -o requireNamespace +o require namespace o set x 1 ? {namespace eval ::o {set x}} 1 ? {::o set x} 1 @@ -185,7 +185,7 @@ Test case namespaces-array Object create o -o requireNamespace +o require namespace ? {o array exists a} 0 ? {namespace eval ::o array exists a} 0 @@ -210,9 +210,9 @@ ########################################### Test case namespaced-var-names Object create o -o requireNamespace +o require namespace Object create o::oo -o::oo requireNamespace +o::oo require namespace ? {::o set ::x 1} 1 ? {info exists ::x} [set ::x] @@ -391,9 +391,9 @@ ############################################### # refined tests for the var resolver under # Tcl namespaces parallelling XOTcl objects -# (! not declared through requireNamespace !) +# (! not declared through require namespace !) # e.g., "info hasnamespace" reports 0 rather -# than 1 as under "requireNamespace" +# than 1 as under "require namespace" ############################################### set ::w 1 @@ -489,7 +489,7 @@ # now with an object namespace Object create o -o requireNamespace +o require namespace # objeval does an objcope, all vars are instance variables o objeval { @@ -560,7 +560,7 @@ # now with namespace Object create o -o requireNamespace +o require namespace # eval does an objcope, all vars are instance variables o objeval {