Index: TODO =================================================================== diff -u -r8744b88b6f0fe062a45bda9d1484d05100ecd747 -r4e0a14b67ffc6ac5087eacf53207f877c33d599f --- TODO (.../TODO) (revision 8744b88b6f0fe062a45bda9d1484d05100ecd747) +++ TODO (.../TODO) (revision 4e0a14b67ffc6ac5087eacf53207f877c33d599f) @@ -2755,6 +2755,9 @@ * Extended regression test * Code cleanup and documentation +-nx.tcl: + * added method "delete" to delete methods and attributes + * extended regression test TODO: Index: library/nx/nx.tcl =================================================================== diff -u -r5c255e27038ce407b8bdf4706a9942c10da1a940 -r4e0a14b67ffc6ac5087eacf53207f877c33d599f --- library/nx/nx.tcl (.../nx.tcl) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) +++ library/nx/nx.tcl (.../nx.tcl) (revision 4e0a14b67ffc6ac5087eacf53207f877c33d599f) @@ -368,6 +368,43 @@ return $r } + # + # Deletion method for attributes and plain methods + # + + Object public method delete {methodName} { + # call explicitly the per-object variant of "info slots" + set slot [::nsf::my "::nx::Object::slot::__info::slots" $methodName] + # + # If we have a slot (e.g. an attribute) we simply delete it. The + # destructor of the slot removes the accessor. + # + if {$slot ne ""} { + $slot destroy + } else { + array set "" [:__resolve_method_path -per-object $methodName] + ::nsf::method::delete $(object) -per-object $(methodName) + } + } + Class public method delete {-per-object:switch methodName} { + if {${per-object}} { + # call explicitly the per-object variant of "delete" + return [::nsf::my ::nsf::classes::nx::Object::delete $methodName] + } else { + set slot [:info slots $methodName] + # + # If we have a slot (e.g. an attribute) we simply delete it. The + # destructor of the slot removes the accessor. + # + if {$slot ne ""} { + $slot destroy + } else { + array set "" [:__resolve_method_path $methodName] + ::nsf::method::delete $(object) $(methodName) + } + } + } + # Add method "require" # Object method require {what args} { @@ -502,7 +539,7 @@ if {[::nsf::object::exists $slotContainer]} { set cmd [list ::nsf::methods::object::info::children -type $type] if {[info exists pattern]} {lappend cmd $pattern} - return [::nsf::my {*}$cmd] + return [$slotContainer {*}$cmd] } } :alias "info vars" ::nsf::methods::object::info::vars @@ -906,8 +943,10 @@ # When slot objects are destroyed, invalidate the object # parameters to reflect the changes # - if {[info exists :domain] && ${:domain} ne "" && [::nsf::is class ${:domain}]} { - ::nsf::invalidateobjectparameter ${:domain} + if {[info exists :domain] && ${:domain} ne ""} { + if {[::nsf::is class ${:domain}]} { + ::nsf::invalidateobjectparameter ${:domain} + } # # delete the accessor # Index: tests/info-method.test =================================================================== diff -u -r53e092b1dceccab3bbd0045bd5b14c1ddedaf68d -r4e0a14b67ffc6ac5087eacf53207f877c33d599f --- tests/info-method.test (.../info-method.test) (revision 53e092b1dceccab3bbd0045bd5b14c1ddedaf68d) +++ tests/info-method.test (.../info-method.test) (revision 4e0a14b67ffc6ac5087eacf53207f877c33d599f) @@ -68,8 +68,8 @@ ? {::nx::Object info lookup methods -source application} "" ? {::nx::Class info lookup methods -source application} "" - set object_methods "alias attribute configure contains copy destroy eval filter forward info method mixin move protected public require volatile" - set class_methods "alias attribute attributes class configure contains copy create destroy eval filter forward info method mixin move new protected public require volatile" + set object_methods "alias attribute configure contains copy delete destroy eval filter forward info method mixin move protected public require volatile" + set class_methods "alias attribute attributes class configure contains copy create delete destroy eval filter forward info method mixin move new protected public require volatile" ? {lsort [::nx::Object info lookup methods -source baseclasses]} $class_methods ? {lsort [::nx::Class info lookup methods -source baseclasses]} $class_methods Index: tests/methods.test =================================================================== diff -u -r5c255e27038ce407b8bdf4706a9942c10da1a940 -r4e0a14b67ffc6ac5087eacf53207f877c33d599f --- tests/methods.test (.../methods.test) (revision 5c255e27038ce407b8bdf4706a9942c10da1a940) +++ tests/methods.test (.../methods.test) (revision 4e0a14b67ffc6ac5087eacf53207f877c33d599f) @@ -524,3 +524,103 @@ ? {c1 info bar foo} "::o-::info" } +# +# Test deletion of object-specific methods/attributes via delete +# method +# a) test attributes +# b) test simple methods +# c) test ensemble methods +# +nx::Test case delete-per-object { + Object create o1 { + :attribute a1 + :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 info methods -path} "{info foo} {info bar foo} foo a1" + ? {o1 info children} "::o1::info ::o1::slot" + + ? {o1 delete bar} "::o1: cannot delete object specific method 'bar'" + + ? {o1 delete a1} "" + ? {o1 info methods -path} "{info foo} {info bar foo} foo" + + ? {o1 delete foo} "" + ? {o1 info methods -path} "{info foo} {info bar foo}" + + ? {o1 delete "info foo"} "" + ? {o1 info methods -path} "{info bar foo}" + + ? {o1 delete "info bar foo"} "" + ? {o1 info methods -path} "" +} + +# +# Test deletion of per-object methods/attributes defined on classes +# via the delete method +# a) test attributes +# b) test simple methods +# c) test ensemble methods +# +nx::Test case delete-per-object-on-class { + Class create C { + :class attribute a1 + :public class method foo {} {return [namespace current]-[namespace which info]} + :public class method "info foo" {} {return [namespace current]-[namespace which info]} + :public class method "info bar foo" {} {return [namespace current]-[namespace which info]} + } + + ? {C class info methods -path} "{info foo} {info bar foo} foo a1" + ? {C info children} "::C::info ::C::slot" + + ? {C delete -per-object bar} "::C: cannot delete object specific method 'bar'" + + ? {C delete -per-object a1} "" + ? {C class info methods -path} "{info foo} {info bar foo} foo" + + ? {C delete -per-object foo} "" + ? {C class info methods -path} "{info foo} {info bar foo}" + + ? {C delete -per-object "info foo"} "" + ? {C class info methods -path} "{info bar foo}" + + ? {C delete -per-object "info bar foo"} "" + ? {C class info methods -path} "" +} + + +# +# Test deletion of methods/attributes defined on classes via the +# delete method +# a) test attributes +# b) test simple methods +# c) test ensemble methods +# +nx::Test case delete-class-level-method { + Class create C { + :attribute a1 + :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]} + } + + ? {C info methods -path} "{info foo} {info bar foo} foo a1" + ? {C info children} "::C::slot" + + ? {C delete bar} "::C: cannot delete method 'bar'" + + ? {C delete a1} "" + ? {C info methods -path} "{info foo} {info bar foo} foo" + + ? {C delete foo} "" + ? {C info methods -path} "{info foo} {info bar foo}" + + ? {C delete "info foo"} "" + ? {C info methods -path} "{info bar foo}" + + ? {C delete "info bar foo"} "" + ? {C info methods -path} "" +} +