Index: TODO =================================================================== diff -u -r9ab7249b16aeb0ea906e3d614fee429edab1cfda -r97e0a189f00e655455aa3a48e44ab61f700eab58 --- TODO (.../TODO) (revision 9ab7249b16aeb0ea906e3d614fee429edab1cfda) +++ TODO (.../TODO) (revision 97e0a189f00e655455aa3a48e44ab61f700eab58) @@ -3258,6 +3258,10 @@ accessors are deactivated for this attribute) * extended regression test +- nx.tcl: extended object-parameter "switch" implementation: + now, accessors of type boolean are created, when type "switch" is used. + + TODO: - strange refcounting bug in 8.6b2 bug-is-86.tcl Index: library/nx/nx.tcl =================================================================== diff -u -r9ab7249b16aeb0ea906e3d614fee429edab1cfda -r97e0a189f00e655455aa3a48e44ab61f700eab58 --- library/nx/nx.tcl (.../nx.tcl) (revision 9ab7249b16aeb0ea906e3d614fee429edab1cfda) +++ library/nx/nx.tcl (.../nx.tcl) (revision 97e0a189f00e655455aa3a48e44ab61f700eab58) @@ -817,7 +817,6 @@ if {[info exists type]} { #if {$type eq "switch"} {error "switch is not allowed as type for object parameter $name"} - if {$type eq "switch"} {set opt(-accessor) false} lappend opts -type $type } lappend opts {*}[array get opt] @@ -1415,13 +1414,15 @@ } { set options "" if {[info exists :type]} { - if {${:type} eq "initcmd"} { + set type ${:type} + if {$type eq "switch" && !$forObjectParameter} {set type boolean} + if {$type eq "initcmd"} { lappend options initcmd - } elseif {[string match ::* ${:type}]} { - lappend options [expr {[::nsf::is metaclass ${:type}] ? "class" : "object"}] type=${:type} + } elseif {[string match ::* $type]} { + lappend options [expr {[::nsf::is metaclass $type] ? "class" : "object"}] type=$type } else { - lappend options ${:type} - if {${:type} ni [list "" "switch" \ + lappend options $type + if {$type ni [list "" "switch" \ "boolean" "integer" "object" "class" \ "metaclass" "baseclass" "parameter" \ "alnum" "alpha" "ascii" "control" "digit" "double" \ @@ -1665,17 +1666,21 @@ lassign [::nx::MetaSlot parseParameterSpec -class $class $spec] \ name parameterOptions class opts + set isSwitch [regsub {\mswitch\M} $parameterOptions boolean parameterOptions] if {[info exists value]} { if {[info exists :$name] && !$nocomplain} { error "Object [self] has already an instance variable named '$name'" } if {$parameterOptions ne ""} { - #puts stderr "::nsf::is $parameterOptions $value" + #puts stderr "*** ::nsf::is $parameterOptions $value // opts=$opts" + # we rely here that the nsf::is error message expresses the implementation limits ::nsf::is -complain $parameterOptions $value } else { set name $spec } set :$name $value + } elseif {$isSwitch} { + set :$name 0 } else { error "Variable definition for '$name' (without value and accessor) is useless" } Index: tests/parameters.test =================================================================== diff -u -r9ab7249b16aeb0ea906e3d614fee429edab1cfda -r97e0a189f00e655455aa3a48e44ab61f700eab58 --- tests/parameters.test (.../parameters.test) (revision 9ab7249b16aeb0ea906e3d614fee429edab1cfda) +++ tests/parameters.test (.../parameters.test) (revision 97e0a189f00e655455aa3a48e44ab61f700eab58) @@ -499,7 +499,7 @@ {d "literal $d"} } - ? {Bar attribute ss:switch} "" + ? {Bar attribute ss:switch} "::nsf::classes::Bar::ss" Bar create bar1 #puts stderr [bar1 objectparameter] @@ -2064,44 +2064,59 @@ ? {lsort [o info vars]} {} } -# -# Testing object parameter switch -# nx::Test case object-parameter-switch { + # Create a class with an attribute of type switch and an instance of + # the class ? {::nx::Class create C { :attribute foo:switch :create c1 }} "::C" - # when the parameter is not specified, the default is false, an - # instance variable is set + # When the object parameter is not specified at creation time, the + # default is false, an instance variable is set with this value ? {lsort [c1 info vars]} {foo} ? {c1 eval {set :foo}} {0} - # when the parameter is specified, the instance variable has a value - # of true (i.e. 1) + # Object parameter of type "switch" are more tricky, since e.g. a + # setter with 0 arguments is a getter. When a setter is built, it + # uses the parameter type boolean instead. + ? {C info methods} "foo" + ? {c1 info lookup method foo} "::nsf::classes::C::foo" + ? {c1 foo} 0 + ? {c1 foo 1} 1 + ? {c1 foo} 1 + + # When the object parameter is specified, the instance variable has + # a value of true (i.e. 1) C create c2 -foo ? {lsort [c2 info vars]} {foo} ? {c2 eval {set :foo}} {1} - # One can pass false as well + # One can pass false (and other values) with the = notation as well C create c3 -foo=false ? {lsort [c3 info vars]} {foo} ? {c3 eval {set :foo}} {false} - # The inverted case, - C attribute {foo2:switch true} + # In the inverted case, the switch has a default of "true". If the + # switch is specified, the valus is "false" + C attribute {foo2:switch 1} C create c4 ? {lsort [c4 info vars]} {foo foo2} - ? {c4 eval {set :foo2}} {true} + ? {c4 eval {set :foo2}} {1} C create c5 -foo2 ? {lsort [c5 info vars]} {foo foo2} ? {c5 eval {set :foo2}} {0} - # Object case, not very useful, boolean would be perfectly fine. + # Object case: variables of type "switch" are like variables of type + # boolean, except that without the specified value argument + # (variable foo below), it sets the the variable to "false". ? {::nx::Object create o1 { - :variable bar:switch 0 - }} {invalid value constraints "switch"} + :variable foo:switch + :variable bar:switch 1 + }} ::o1 + ? {o1 eval {set :foo}} 0 + ? {o1 eval {set :bar}} 1 + } \ No newline at end of file