Index: generic/predefined.h =================================================================== diff -u -r9a128ffc80f0c429d885af38e92c50b253cdb9e8 -r4d21376ac1245e34cb5a5f52da893072f311d3a9 --- generic/predefined.h (.../predefined.h) (revision 9a128ffc80f0c429d885af38e92c50b253cdb9e8) +++ generic/predefined.h (.../predefined.h) (revision 4d21376ac1245e34cb5a5f52da893072f311d3a9) @@ -34,7 +34,7 @@ "::xotcl::method [self] -per-object $name $arguments $body {*}$conditions}\n" "Class eval {\n" ":method object {what args} {\n" -"if {$what in [list \"alias\" \"forward\" \"method\" \"setter\"]} {\n" +"if {$what in [list \"alias\" \"attribute\" \"forward\" \"method\" \"setter\"]} {\n" "return [::xotcl::dispatch [self] ::xotcl::classes::xotcl2::Object::$what {*}$args]}\n" "if {$what in [list \"info\"]} {\n" "return [::xotcl2::objectInfo [lindex $args 0] [self] {*}[lrange $args 1 end]]}\n" @@ -48,13 +48,13 @@ "::xotcl::methodproperty [self] unknown protected 1}\n" "Object eval {\n" ":method public {args} {\n" -"set p [lsearch -regexp $args {^(method|alias|forward|setter)$}]\n" +"set p [lsearch -regexp $args {^(method|alias|attribute|forward|setter)$}]\n" "if {$p == -1} {error \"$args is not a method defining method\"}\n" "set r [{*}:$args]\n" "::xotcl::methodproperty [self] $r protected false\n" "return $r}\n" ":method protected {args} {\n" -"set p [lsearch -regexp $args {^(method|alias|forward|setter)$}]\n" +"set p [lsearch -regexp $args {^(method|alias|attribute|forward|setter)$}]\n" "if {$p == -1} {error \"$args is not a method defining command\"}\n" "set r [{*}:$args]\n" "::xotcl::methodproperty [self] $r [self proc] true\n" @@ -150,7 +150,7 @@ "if {![::xotcl::is ${slotParent} object]} {\n" "::xotcl2::Object create ${slotParent}}\n" "return ${slotParent}::$name}\n" -"::xotcl::MetaSlot method createFromParameterSyntax {target {-initblock \"\"} value default:optional} {\n" +"::xotcl::MetaSlot method createFromParameterSyntax {target -per-object:switch {-initblock \"\"} value default:optional} {\n" "set opts [list]\n" "set colonPos [string first : $value]\n" "if {$colonPos == -1} {\n" @@ -170,7 +170,13 @@ "lappend opts -type $type}\n" "if {[info exists default]} {\n" "lappend opts -default $default}\n" -":create [:slotName $name $target] {*}$opts $initblock}\n" +"if {${per-object}} {\n" +"lappend opts -per-object true\n" +"set info ObjectInfo} else {\n" +"set info ClassInfo}\n" +":create [:slotName $name $target] {*}$opts $initblock\n" +"puts stderr \"::xotcl::cmd::${info}::method $target name $name => [::xotcl::cmd::${info}::method $target name $name]\"\n" +"::xotcl::cmd::${info}::method $target name $name}\n" "::xotcl::MetaSlot create ::xotcl::Slot\n" "::xotcl::MetaSlot create ::xotcl::ObjectParameterSlot\n" "::xotcl::relation ::xotcl::ObjectParameterSlot superclass ::xotcl::Slot\n" @@ -231,7 +237,7 @@ "lappend methods $m}\n" "error \"Method '$method' unknown for slot [::xotcl::self]; valid are: {[lsort $methods]]}\"}\n" "::xotcl::ObjectParameterSlot public method destroy {} {\n" -"if {${:domain} ne \"\" && [::xotcl::is ${:domain} object]} {\n" +"if {${:domain} ne \"\" && [::xotcl::is ${:domain} class]} {\n" "${:domain} __invalidateobjectparameter}\n" "next}\n" "::xotcl::ObjectParameterSlot protected method init {args} {\n" @@ -240,7 +246,10 @@ "if {${:domain} ne \"\"} {\n" "if {![info exists :methodname]} {\n" "set :methodname ${:name}}\n" -"${:domain} __invalidateobjectparameter\n" +"if {[::xotcl::is ${:domain} class]} {\n" +"${:domain} __invalidateobjectparameter}\n" +"if {${:per-object} && [info exists :default] } {\n" +"::xotcl::setinstvar ${:domain} ${:name} ${:default}}\n" "set cl [expr {${:per-object} ? \"Object\" : \"Class\"}]\n" "::xotcl::forward ${:domain} ${:name} \\\n" "${:manager} \\\n" @@ -423,8 +432,10 @@ "set setterParam ${:name}}\n" "::xotcl::setter ${:domain} {*}$perObject $setterParam}}\n" "::xotcl::Attribute mixin add ::xotcl::Attribute::Optimizer\n" -"::xotcl2::Object method attribute {spec {-slotclass ::xotcl::Attribute} {initblock \"\"}} {\n" +"::xotcl2::Class method attribute {spec {-slotclass ::xotcl::Attribute} {initblock \"\"}} {\n" "$slotclass createFromParameterSyntax [self] -initblock $initblock {*}$spec}\n" +"::xotcl2::Object method attribute {spec {-slotclass ::xotcl::Attribute} {initblock \"\"}} {\n" +"$slotclass createFromParameterSyntax [self] -per-object -initblock $initblock {*}$spec}\n" "::xotcl2::Class public method parameter arglist {\n" "foreach arg $arglist {\n" "::xotcl::Attribute createFromParameterSyntax [self] {*}$arg}\n" Index: generic/predefined.xotcl =================================================================== diff -u -r9a128ffc80f0c429d885af38e92c50b253cdb9e8 -r4d21376ac1245e34cb5a5f52da893072f311d3a9 --- generic/predefined.xotcl (.../predefined.xotcl) (revision 9a128ffc80f0c429d885af38e92c50b253cdb9e8) +++ generic/predefined.xotcl (.../predefined.xotcl) (revision 4d21376ac1245e34cb5a5f52da893072f311d3a9) @@ -72,7 +72,7 @@ # method-modifier for object specific methos :method object {what args} { - if {$what in [list "alias" "forward" "method" "setter"]} { + if {$what in [list "alias" "attribute" "forward" "method" "setter"]} { return [::xotcl::dispatch [self] ::xotcl::classes::xotcl2::Object::$what {*}$args] } if {$what in [list "info"]} { @@ -100,7 +100,7 @@ # method modifier "public" :method public {args} { - set p [lsearch -regexp $args {^(method|alias|forward|setter)$}] + set p [lsearch -regexp $args {^(method|alias|attribute|forward|setter)$}] if {$p == -1} {error "$args is not a method defining method"} set r [{*}:$args] ::xotcl::methodproperty [self] $r protected false @@ -109,7 +109,7 @@ # method modifier "protected" :method protected {args} { - set p [lsearch -regexp $args {^(method|alias|forward|setter)$}] + set p [lsearch -regexp $args {^(method|alias|attribute|forward|setter)$}] if {$p == -1} {error "$args is not a method defining command"} set r [{*}:$args] ::xotcl::methodproperty [self] $r [self proc] true @@ -308,7 +308,7 @@ return ${slotParent}::$name } - ::xotcl::MetaSlot method createFromParameterSyntax {target {-initblock ""} value default:optional} { + ::xotcl::MetaSlot method createFromParameterSyntax {target -per-object:switch {-initblock ""} value default:optional} { set opts [list] set colonPos [string first : $value] if {$colonPos == -1} { @@ -339,8 +339,15 @@ if {[info exists default]} { lappend opts -default $default } + if {${per-object}} { + lappend opts -per-object true + set info ObjectInfo + } else { + set info ClassInfo + } :create [:slotName $name $target] {*}$opts $initblock + return [::xotcl::cmd::${info}::method $target name $name] } # ::xotcl::MetaSlot public method new args { @@ -460,7 +467,7 @@ } ::xotcl::ObjectParameterSlot public method destroy {} { - if {${:domain} ne "" && [::xotcl::is ${:domain} object]} { + if {${:domain} ne "" && [::xotcl::is ${:domain} class]} { ${:domain} __invalidateobjectparameter } next @@ -474,7 +481,12 @@ if {![info exists :methodname]} { set :methodname ${:name} } - ${:domain} __invalidateobjectparameter + if {[::xotcl::is ${:domain} class]} { + ${:domain} __invalidateobjectparameter + } + if {${:per-object} && [info exists :default] } { + ::xotcl::setinstvar ${:domain} ${:name} ${:default} + } set cl [expr {${:per-object} ? "Object" : "Class"}] #puts stderr "Slot [self] init, forwarder on ${:domain}" ::xotcl::forward ${:domain} ${:name} \ @@ -802,10 +814,12 @@ ############################################ # Define method "attribute" for convenience ############################################ - ::xotcl2::Object method attribute {spec {-slotclass ::xotcl::Attribute} {initblock ""}} { + ::xotcl2::Class method attribute {spec {-slotclass ::xotcl::Attribute} {initblock ""}} { $slotclass createFromParameterSyntax [self] -initblock $initblock {*}$spec } - + ::xotcl2::Object method attribute {spec {-slotclass ::xotcl::Attribute} {initblock ""}} { + $slotclass createFromParameterSyntax [self] -per-object -initblock $initblock {*}$spec + } ############################################ # Define method "parameter" for backward # compatibility and convenience Index: library/lib/test.xotcl =================================================================== diff -u -r2c178b51df714386e72cfcb05f89c89995668b2d -r4d21376ac1245e34cb5a5f52da893072f311d3a9 --- library/lib/test.xotcl (.../test.xotcl) (revision 2c178b51df714386e72cfcb05f89c89995668b2d) +++ library/lib/test.xotcl (.../test.xotcl) (revision 4d21376ac1245e34cb5a5f52da893072f311d3a9) @@ -55,6 +55,7 @@ if {[info exists arg]} { foreach o [Object info instances -closure] {set pre_exist($o) 1} namespace eval :: [list [self] eval $arg] + #:eval $arg foreach o [Object info instances -closure] { if {[info exists pre_exist($o)]} continue #puts "must destroy $o" Index: tests/method-modifiers.xotcl =================================================================== diff -u -r210eab6d9149846d5d6a6a8e0fa74e232ca5b6de -r4d21376ac1245e34cb5a5f52da893072f311d3a9 --- tests/method-modifiers.xotcl (.../method-modifiers.xotcl) (revision 210eab6d9149846d5d6a6a8e0fa74e232ca5b6de) +++ tests/method-modifiers.xotcl (.../method-modifiers.xotcl) (revision 4d21376ac1245e34cb5a5f52da893072f311d3a9) @@ -71,78 +71,88 @@ # create a fresh object (different from c1) C create c2 # test scripted class level methods -Test case scripted-class-level-methods -? {c2 plain_method} "plain_method" -? {c2 public_method} "public_method" -? {catch {c2 protected_method}} 1 -? {::xotcl::dispatch c2 protected_method} "protected_method" +Test case scripted-class-level-methods { + ? {c2 plain_method} "plain_method" + ? {c2 public_method} "public_method" + ? {catch {c2 protected_method}} 1 + ? {::xotcl::dispatch c2 protected_method} "protected_method" +} # class level forwards -Test case class-level-forwards -? {c2 plain_forward} "plain_method" -? {c2 public_forward} "public_method" -? {catch {c2 protected_forward}} 1 -? {::xotcl::dispatch c2 protected_forward} "protected_method" +Test case class-level-forwards { + ? {c2 plain_forward} "plain_method" + ? {c2 public_forward} "public_method" + ? {catch {c2 protected_forward}} 1 + ? {::xotcl::dispatch c2 protected_forward} "protected_method" +} # class level setter -Test case class-level-setter -? {c2 plain_setter 1} "1" -? {c2 public_setter 2} "2" -? {catch {c2 protected_setter 3}} 1 -? {::xotcl::dispatch c2 protected_setter 4} "4" +Test case class-level-setter { + ? {c2 plain_setter 1} "1" + ? {c2 public_setter 2} "2" + ? {catch {c2 protected_setter 3}} 1 + ? {::xotcl::dispatch c2 protected_setter 4} "4" +} # class level alias ....TODO: wanted behavior of [self proc]? not "plain_alias"? -Test case class-level-alias -? {c2 plain_alias} "plain_method" -? {c2 public_alias} "public_method" -? {catch {c2 protected_alias}} 1 -? {::xotcl::dispatch c2 protected_alias} "protected_method" +Test case class-level-alias { + ? {c2 plain_alias} "plain_method" + ? {c2 public_alias} "public_method" + ? {catch {c2 protected_alias}} 1 + ? {::xotcl::dispatch c2 protected_alias} "protected_method" +} ########### # scripted class-object level methods -Test case scripted-class-object-level -? {C plain_object_method} "plain_object_method" -? {C public_object_method} "public_object_method" -? {catch {C protected_object_method}} 1 -? {::xotcl::dispatch C protected_object_method} "protected_object_method" +Test case scripted-class-object-level { + ? {C plain_object_method} "plain_object_method" + ? {C public_object_method} "public_object_method" + ? {catch {C protected_object_method}} 1 + ? {::xotcl::dispatch C protected_object_method} "protected_object_method" +} # class-object level forwards -Test case class-object-level-forwards -? {C plain_object_forward} "plain_object_method" -? {C public_object_forward} "public_object_method" -? {catch {C protected_object_forward}} 1 -? {::xotcl::dispatch C protected_object_forward} "protected_object_method" +Test case class-object-level-forwards { + ? {C plain_object_forward} "plain_object_method" + ? {C public_object_forward} "public_object_method" + ? {catch {C protected_object_forward}} 1 + ? {::xotcl::dispatch C protected_object_forward} "protected_object_method" +} # class-object level setter -Test case class-object-level-setter -? {C plain_object_setter 1} "1" -? {C public_object_setter 2} "2" -? {catch {C protected_object_setter 3}} 1 -? {::xotcl::dispatch C protected_object_setter 4} "4" +Test case class-object-level-setter { + ? {C plain_object_setter 1} "1" + ? {C public_object_setter 2} "2" + ? {catch {C protected_object_setter 3}} 1 + ? {::xotcl::dispatch C protected_object_setter 4} "4" +} # class-object level alias ....TODO: wanted behavior of [self proc]? not "plain_alias"? -Test case class-object-level-alias -? {C plain_object_alias} "plain_object_method" -? {C public_object_alias} "public_object_method" -? {catch {C protected_object_alias}} 1 -? {::xotcl::dispatch C protected_object_alias} "protected_object_method" +Test case class-object-level-alias { + ? {C plain_object_alias} "plain_object_method" + ? {C public_object_alias} "public_object_method" + ? {catch {C protected_object_alias}} 1 + ? {::xotcl::dispatch C protected_object_alias} "protected_object_method" +} ########### # scripted object level methods -Test case scripted-object-level-methods -? {c1 plain_object_method} "plain_object_method" -? {c1 public_object_method} "public_object_method" -? {catch {c1 protected_object_method}} 1 -? {::xotcl::dispatch c1 protected_object_method} "protected_object_method" +Test case scripted-object-level-methods { + ? {c1 plain_object_method} "plain_object_method" + ? {c1 public_object_method} "public_object_method" + ? {catch {c1 protected_object_method}} 1 + ? {::xotcl::dispatch c1 protected_object_method} "protected_object_method" +} # object level forwards -Test case object-level-forwards -? {c1 plain_object_forward} "plain_object_method" -? {c1 public_object_forward} "public_object_method" -? {catch {c1 protected_object_forward}} 1 -? {::xotcl::dispatch c1 protected_object_forward} "protected_object_method" +Test case object-level-forwards { + ? {c1 plain_object_forward} "plain_object_method" + ? {c1 public_object_forward} "public_object_method" + ? {catch {c1 protected_object_forward}} 1 + ? {::xotcl::dispatch c1 protected_object_forward} "protected_object_method" +} # object level setter Test case object-level-setter @@ -152,72 +162,120 @@ ? {::xotcl::dispatch c1 protected_object_setter 4} "4" # object level alias ....TODO: wanted behavior of [self proc]? not "plain_alias"? -Test case object-level-alias -? {c1 plain_object_alias} "plain_object_method" -? {c1 public_object_alias} "public_object_method" -? {catch {c1 protected_object_alias}} 1 -? {::xotcl::dispatch c1 protected_object_alias} "protected_object_method" +Test case object-level-alias { + ? {c1 plain_object_alias} "plain_object_method" + ? {c1 public_object_alias} "public_object_method" + ? {catch {c1 protected_object_alias}} 1 + ? {::xotcl::dispatch c1 protected_object_alias} "protected_object_method" -? {lsort [c1 info methods]} \ - "plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter" -? {lsort [C object info methods]} \ - "plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter s3" + ? {lsort [c1 info methods]} \ + "plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter" + ? {lsort [C object info methods]} \ + "plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter s3" +} C destroy -Class create C -Class create M +Test case mixinguards { + # define a Class C and mixin class M + Class create C + Class create M + # register the mixin on C as a class mixin and define a class + # mixinguard + C mixin M + C mixinguard M {1 == 1} + ? {C info mixinguard M} "1 == 1" + C mixinguard M {} + ? {C info mixinguard M} "" -Test case mixinguards -# define a Class C and mixin class M -Class create C -Class create M -# register the mixin on C as a class mixin and define a class -# mixinguard -C mixin M -C mixinguard M {1 == 1} -? {C info mixinguard M} "1 == 1" -C mixinguard M {} -? {C info mixinguard M} "" + # now the same as object mixin and object mixin guard + C object mixin M + C object mixinguard M {1 == 1} + ? {C object info mixinguard M} "1 == 1" + C object mixinguard M {} + ? {C object info mixinguard M} "" +} -# now the same as object mixin and object mixin guard -C object mixin M -C object mixinguard M {1 == 1} -? {C object info mixinguard M} "1 == 1" -C object mixinguard M {} -? {C object info mixinguard M} "" - -Test case mixin-via-objectparam -# add an object and class mixin via object-parameter and via slots -Class create M1; Class create M2; Class create M3; Class create M4 -Class create C -mixin M1 -object-mixin M2 { - :mixin add M3 - :object mixin add M4 +Test case mixin-via-objectparam { + # add an object and class mixin via object-parameter and via slots + Class create M1; Class create M2; Class create M3; Class create M4 + Class create C -mixin M1 -object-mixin M2 { + :mixin add M3 + :object mixin add M4 + } + + ? {lsort [C object info mixin]} "::M2 ::M4" + ? {lsort [C info mixin]} "::M1 ::M3" + C destroy + M1 destroy; M2 destroy; M3 destroy; M4 destroy; } -? {lsort [C object info mixin]} "::M2 ::M4" -? {lsort [C info mixin]} "::M1 ::M3" -C destroy -M1 destroy; M2 destroy; M3 destroy; M4 destroy; - # testing next via nonpos-args -Test case next-from-nonpos-args - -Object create o { - :method bar {-y:required -x:required} { - #puts stderr "+++ o x=$x, y=$y [self args] ... next [self next]" - return [list x $x y $y [self args]] +Test case next-from-nonpos-args { + + Object create o { + :method bar {-y:required -x:required} { + #puts stderr "+++ o x=$x, y=$y [self args] ... next [self next]" + return [list x $x y $y [self args]] + } } -} -Class create M { - :method bar {-x:required -y:required} { - #puts stderr "+++ M x=$x, y=$y [self args] ... next [self next]" - return [list x $x y $y [self args] -- {*}[next]] + Class create M { + :method bar {-x:required -y:required} { + #puts stderr "+++ M x=$x, y=$y [self args] ... next [self next]" + return [list x $x y $y [self args] -- {*}[next]] + } } + + o mixin M + ? {o bar -x 13 -y 14} "x 13 y 14 {-x 13 -y 14} -- x 13 y 14 {-x 13 -y 14}" + ? {o bar -y 14 -x 13} "x 13 y 14 {-y 14 -x 13} -- x 13 y 14 {-y 14 -x 13}" } -o mixin M -puts stderr ===== -? {o bar -x 13 -y 14} "x 13 y 14 {-x 13 -y 14} -- x 13 y 14 {-x 13 -y 14}" -puts stderr ===== -? {o bar -y 14 -x 13} "x 13 y 14 {-y 14 -x 13} -- x 13 y 14 {-y 14 -x 13}" \ No newline at end of file + + +# +Test case attribute-method { + + Class create C { + set x [:attribute a] + ? [list set _ $x] "::xotcl::classes::C::a" + + # attribute with default + :attribute {b b1} + :public attribute {c c1} + :protected attribute {d d1} + + set X [:object attribute A] + ? [list set _ $X] "::C::A" + + # object attribute with default + :object attribute {B B2} + :public object attribute {C C2} + :protected object attribute {D D2} + } + + C create c1 -a 1 + ? {c1 a} 1 + ? {c1 b} b1 + ? {c1 c} c1 + ? {c1 d} "::c1: unable to dispatch method 'd'" + + ? {C A 2} 2 + ? {C B} B2 + ? {C C} C2 + ? {C D} "Method 'D' unknown for ::C. Consider '::C create D ' instead of '::C D '" + + Object create o { + set x [:attribute a] + ? [list set _ $x] "::o::a" + + # attribute with default + :attribute {b b1} + :public attribute {c c1} + :protected attribute {d d1} + } + ? {o a 2} 2 + ? {o b} b1 + ? {o c} c1 + ? {o d} "::o: unable to dispatch method 'd'" +} \ No newline at end of file Index: tests/parameters.xotcl =================================================================== diff -u -r2c178b51df714386e72cfcb05f89c89995668b2d -r4d21376ac1245e34cb5a5f52da893072f311d3a9 --- tests/parameters.xotcl (.../parameters.xotcl) (revision 2c178b51df714386e72cfcb05f89c89995668b2d) +++ tests/parameters.xotcl (.../parameters.xotcl) (revision 4d21376ac1245e34cb5a5f52da893072f311d3a9) @@ -2,6 +2,16 @@ package require xotcl::test ::xotcl::use xotcl2 +Test case dummy { + puts current=[::namespace current] + set o [Object create o] + puts o=$o + + ? {::xotcl::is ::o object} 1 +} +? {::xotcl::is ::o object} 0 +#exit + ####################################################### # valuecheck ####################################################### @@ -56,7 +66,6 @@ ? {::xotcl::valuecheck sex,slot=::paramManager female} "1" } - ####################################################### # cononical feature table ####################################################### @@ -206,14 +215,6 @@ # test passed arguments ####################################################### -Test case dummy { - set o [Object create o] - puts o=$o-current=[::namespace current] - - ? {::xotcl::is ::o object} 1 -} -? {::xotcl::is ::o object} 0 - Test case passed-arguments { Class create C -parameter {a {b:boolean} {c 1}}