Index: doc/migration1-2.html =================================================================== diff -u -rc619db7db573de1047ec1810dc0a8dc4d86ce98d -reef622da1b387cfd1dd68babeb0bfecfbae5caa3 --- doc/migration1-2.html (.../migration1-2.html) (revision c619db7db573de1047ec1810dc0a8dc4d86ce98d) +++ doc/migration1-2.html (.../migration1-2.html) (revision eef622da1b387cfd1dd68babeb0bfecfbae5caa3) @@ -9,13 +9,16 @@ color: black; } table i { - font-size: 80%; + font-size: 80%; } table td code i { - font-style: italic; - color: green; + font-style: italic; + color: green; } - +pre i { + font-style: italic; + color: green; +} th {color: #888888;} td hr { color: #FFFFFF; @@ -39,6 +42,7 @@ } table td { width: 400; + padding: 10px; border:1px solid #AAAAAA; } @@ -52,15 +56,48 @@

Supporting XOTcl 1 in XOTcl 2

-

-... multiple object systems .... -

-::xotcl::use xotcl1 -

-::xotcl::use xotcl2 -

-describe, what ::xotcl::use does +

In general, the XOTcl 2 environment supports multiple object +systems concurrently. Effectively, every object system has different +base classes for creating both, objects and classes. Therefore, the +object systems can have different different interfaces and names of +builtin methods. Currently, XOTcl 2 supports primarily XOTcl 1 and +XOTcl 2 (XOTcl 1 provides about twice as many predefined builtin +methods).

+

The support for multiple object systems can be used to load XOTcl +1 and XOTcl 2 scripts into the same interpreter. This makes migration +from XOTcl 1 to XOTcl 2 easier. The XOTcl environment provides the +predefined command ::xotcl::use to make switching between these +objects systems convenient. The following example script shows a single +script defining classes of XOTcl 1 and 2:

+ +

+   package require XOTcl
+
+   namespace eval mypackage {
+
+      # Some definitions for XOTcl 1
+      ::xotcl::use xotcl1
+
+      Class C1
+      C1 instproc foo {} {puts "hello world"}
+
+      # Some definitions for XOTcl 2
+      ::xotcl::use xotcl2
+
+      Class create C2 {
+         .method foo {} {puts "hello world"}
+      }
+   }
+
+ +

"Switching" effectively means the load some libraries if needed +and to import either the XOTcl 1 or XOTcl 2 base classes as +Object and Class into the current namespace. +If the import is not wanted, just use package require to +load the necessary pieces. +

+

XOTcl 1 Idioms in XOTcl 2

Defining Objects and Classes

@@ -118,7 +155,16 @@ +

Resolvers

+XOTcl 2 defines Tcl resolvers for method and variable names to refer +to object specific behavior. Withing method bodies these resolver +treat names staring with a dot "." specially. If one wants to refer to +a name starting with a "." (e.g. the name of a Tcl function starts +with a dot), the dot has to be duplicated, or one has to use the +usual namespace prefix "::" to refer to a namespaced entity. Note that +the XOTcl 2 resolver is used in the XOTcl 1 environment as well. +

Invoking Methods

@@ -151,6 +197,30 @@
XOTcl 1XOTcl 2
+ + + + @@ -393,6 +463,35 @@ object as shown in examples above.

+

List filter or mixins

+
XOTcl 1XOTcl 2
Class C
+ C instproc foo args {
+   # method scoped variable a
+   set a 1
+   # instance variable b
+   my instvar b
+   set b 2
+   # global variable/namespaced variable c
+   set ::c 3
+ }
+
Class create C {
+   .method foo args {...}
+     # method scoped variable a
+     set a 1
+     # instance variable b
+     set .b 2
+     # global variable/namespaced variable c
+     set ::c 3
+   }
+ }
+
my set varname value set .varname value
+ + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl 1XOTcl 2
obj info filter ?-order? ?-guards? ?pattern?obj info filter ?-order? ?-guards? ?pattern?
cls info filter ?-order? ?-guards? ?pattern?cls object info filter ?-order? ?-guards? ?pattern?
cls info instfilter ?-order? ?-guards? ?pattern?cls info filter ?-order? ?-guards? ?pattern?
obj info mixin ?-order? ?-guards? ?pattern?obj info mixin ?-order? ?-guards? ?pattern?
cls info mixin ?-order? ?-guards? ?pattern?cls object info mixin ?-order? ?-guards? ?pattern?
cls info instmixin ?-order? ?-guards? ?pattern?cls info mixin ?-order? ?-guards? ?pattern?
+

List definition of methods defined by aliases, setters or forwarders

@@ -402,8 +501,8 @@ - - cls ?object? info method definition methodName +
XOTcl 1XOTcl 2
n.a.cls info method definition methodName

List fully qualified name of method

@@ -415,8 +514,8 @@ n.a. - cls info method name methodName - cls ?object? info method name methodName +

List type of a method

@@ -428,12 +527,79 @@ n.a. - cls info method type methodName - cls ?object? info method type methodName + +

List the scope of mixin classes

+ + + + + + + + + + + + + + +
XOTcl 1XOTcl 2
cls info mixinof ?-closure? ?pattern?cls info mixinof -scope object ?-closure? ?pattern?
cls info instmixinof ?-closure? ?pattern?cls info mixinof -scope class ?-closure? ?pattern?
n.a.cls info mixinof -scope all ?-closure? ?pattern?
+

Check properties of object and classes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl 1XOTcl 2
obj istype sometype + ::xotcl::is obj type sometype
+
+ obj info is type sometype +
obj ismixin cls + ::xotcl::is obj mixin cls
+
+ obj info is mixin cls +
obj isclass ?cls? + ::xotcl::is obj|cls class
+
+ obj info is class +
obj ismetaclass cls::xotcl::is obj|cls metaclass +
+ obj info is metaclass +
n.a.::xotcl::is cls baseclass +
+ cls info is baseclass +
obj isobject obj2::xotcl::is obj|obj2 object +
+ obj info is object +
+ +

Predefined Methods

Dispatch, Aliases, etc.

Assertions

@@ -479,7 +645,48 @@

Method Protection

+

Incompatibilities

+ +

Namespace resolvers

+

The XOTcl 2 namespace resolvers are use as well when XOTcl 1 is used +within XOTcl 2. +

+ +

Stronger Checking

+

XOTcl 2 performs stronger checking than XOTcl 1. The requiredness +of slots in XOTcl 1 was just a comment, while XOTcl 2 enforces it. +

+ +

Different results

+ + + + +

Exit handlers

+

+The exit hander interface changed from a method of +::xotcl::Object into procs in the ::xotcl +namespace. XOTcl 2 provides now: +

+   ::xotcl::setExitHandler script
+   ::xotcl::getExitHandler
+   ::xotcl::unsetExitHandler
+
+ +
- Last modified: Tue Jan 5 19:00:20 CET 2010 + Last modified: Tue Jan 12 11:35:29 CET 2010 Index: generic/predefined.h =================================================================== diff -u -rf279bf06b31139084edd5136824a1e2622265e00 -reef622da1b387cfd1dd68babeb0bfecfbae5caa3 --- generic/predefined.h (.../predefined.h) (revision f279bf06b31139084edd5136824a1e2622265e00) +++ generic/predefined.h (.../predefined.h) (revision eef622da1b387cfd1dd68babeb0bfecfbae5caa3) @@ -8,7 +8,7 @@ "set cmdName [namespace tail $cmd]\n" "if {$cmdName in [list \"instvar\"]} continue\n" "::xotcl::alias Object $cmdName $cmd}\n" -"::xotcl::alias Object eval -objscope ::eval\n" +"::xotcl::alias Object eval -nonleaf ::eval\n" "foreach cmd [info command ::xotcl::cmd::Class::*] {\n" "set cmdName [namespace tail $cmd]\n" "::xotcl::alias Class $cmdName $cmd}\n" @@ -32,7 +32,7 @@ "if {[info exists precondition]} {lappend conditions -precondition $precondition}\n" "if {[info exists postcondition]} {lappend conditions -postcondition $postcondition}\n" "::xotcl::method [self] -per-object $name $arguments $body {*}$conditions}\n" -"::xotcl::dispatch Class -objscope ::eval {\n" +"Class eval {\n" ".method object {what args} {\n" "if {$what in [list \"alias\" \"forward\" \"method\" \"setter\"]} {\n" "return [::xotcl::dispatch [self] ::xotcl::classes::xotcl2::Object::$what {*}$args]}\n" @@ -46,7 +46,7 @@ "error \"Method '$m' unknown for [self].\\\n" "Consider '[self] create $m $args' instead of '[self] $m $args'\"}\n" "::xotcl::methodproperty [self] unknown protected 1}\n" -"::xotcl::dispatch Object -objscope ::eval {\n" +"Object eval {\n" ".method public {args} {\n" "set p [lsearch -regexp $args {^(method|alias|forward|setter)$}]\n" "if {$p == -1} {error \"$args is not a method defining method\"}\n" @@ -86,7 +86,7 @@ "::xotcl::setter [self] $methodName}}\n" "Object create ::xotcl2::objectInfo\n" "Object create ::xotcl2::classInfo\n" -"::xotcl::dispatch objectInfo -objscope ::eval {\n" +"objectInfo eval {\n" ".alias is ::xotcl::is\n" ".public method info {obj} {\n" "set methods [list]\n" @@ -96,7 +96,16 @@ "return \"valid options are: [join [lsort $methods] {, }]\"}\n" ".method unknown {method obj args} {\n" "error \"[::xotcl::self] unknown info option \\\"$method\\\"; [$obj info info]\"}}\n" -"::xotcl::dispatch classInfo -objscope ::eval {\n" +"classInfo eval {\n" +".public method mixinof {obj -closure:switch {-scope all} pattern:optional} {\n" +"set withClosure [expr {$closure ? \"-closure\" : \"\"}]\n" +"set withPattern [expr {[info exists pattern] ? $pattern : \"\"}]\n" +"if {$scope eq \"all\"} {\n" +"set r [::xotcl::cmd::ClassInfo::object-mixin-of $obj {*}$withClosure {*}$withPattern]\n" +"foreach c [::xotcl::cmd::ClassInfo::class-mixin-of $obj {*}$withClosure] {\n" +"lappend r {*}[$c info instances {*}$withPattern]}\n" +"return [lsort -unique $r]} else {\n" +"return [::xotcl::cmd::ClassInfo::$scope-mixin-of $obj {*}$withClosure {*}$withPattern]}}\n" ".alias is ::xotcl::is\n" ".alias classparent ::xotcl::cmd::ObjectInfo::parent\n" ".alias classchildren ::xotcl::cmd::ObjectInfo::children\n" @@ -107,6 +116,7 @@ "::xotcl::alias ::xotcl2::classInfo [namespace tail $cmd] $cmd}\n" "foreach cmd [info command ::xotcl::cmd::ClassInfo::*] {\n" "set cmdName [namespace tail $cmd]\n" +"if {$cmdName in [list \"object-mixin-of\" \"class-mixin-of\"]} continue\n" "::xotcl::alias ::xotcl2::classInfo $cmdName $cmd}\n" "unset cmd\n" "Object forward info -onerror ::xotcl::infoError ::xotcl2::objectInfo %1 {%@2 %self}\n" Index: generic/predefined.xotcl =================================================================== diff -u -rf279bf06b31139084edd5136824a1e2622265e00 -reef622da1b387cfd1dd68babeb0bfecfbae5caa3 --- generic/predefined.xotcl (.../predefined.xotcl) (revision f279bf06b31139084edd5136824a1e2622265e00) +++ generic/predefined.xotcl (.../predefined.xotcl) (revision eef622da1b387cfd1dd68babeb0bfecfbae5caa3) @@ -25,7 +25,7 @@ #foreach cmd {array append eval incr lappend set subst unset trace} { # ::xotcl::alias Object $cmd -objscope ::$cmd #} - ::xotcl::alias Object eval -objscope ::eval + ::xotcl::alias Object eval -nonleaf ::eval # provide the standard command set for Class foreach cmd [info command ::xotcl::cmd::Class::*] { @@ -68,7 +68,7 @@ } # define method modifiers "object", "public" and "protected" - ::xotcl::dispatch Class -objscope ::eval { + Class eval { # method-modifier for object specific methos .method object {what args} { @@ -96,7 +96,7 @@ } - ::xotcl::dispatch Object -objscope ::eval { + Object eval { # method modifier "public" .method public {args} { @@ -187,9 +187,10 @@ # It would be nice to do here "objectInfo configure {.alias ..}", but # we have no working objectparameter yet due to bootstrapping # - ::xotcl::dispatch objectInfo -objscope ::eval { + objectInfo eval { .alias is ::xotcl::is + # info info .public method info {obj} { set methods [list] foreach name [::xotcl::cmd::ObjectInfo::methods [self]] { @@ -198,13 +199,27 @@ } return "valid options are: [join [lsort $methods] {, }]" } - + .method unknown {method obj args} { error "[::xotcl::self] unknown info option \"$method\"; [$obj info info]" } } - ::xotcl::dispatch classInfo -objscope ::eval { + classInfo eval { + .public method mixinof {obj -closure:switch {-scope all} pattern:optional} { + # scope eq "all" or "object" returns objects, scope eq "class" returns classes + set withClosure [expr {$closure ? "-closure" : ""}] + set withPattern [expr {[info exists pattern] ? $pattern : ""}] + if {$scope eq "all"} { + set r [::xotcl::cmd::ClassInfo::object-mixin-of $obj {*}$withClosure {*}$withPattern] + foreach c [::xotcl::cmd::ClassInfo::class-mixin-of $obj {*}$withClosure] { + lappend r {*}[$c info instances {*}$withPattern] + } + return [lsort -unique $r] + } else { + return [::xotcl::cmd::ClassInfo::$scope-mixin-of $obj {*}$withClosure {*}$withPattern] + } + } .alias is ::xotcl::is .alias classparent ::xotcl::cmd::ObjectInfo::parent .alias classchildren ::xotcl::cmd::ObjectInfo::children @@ -218,10 +233,12 @@ } foreach cmd [info command ::xotcl::cmd::ClassInfo::*] { set cmdName [namespace tail $cmd] + if {$cmdName in [list "object-mixin-of" "class-mixin-of"]} continue ::xotcl::alias ::xotcl2::classInfo $cmdName $cmd } unset cmd + # register method "info" on Object and Class Object forward info -onerror ::xotcl::infoError ::xotcl2::objectInfo %1 {%@2 %self} Class forward info -onerror ::xotcl::infoError ::xotcl2::classInfo %1 {%@2 %self} Index: library/lib/xotcl1.xotcl =================================================================== diff -u -re5b7b9261b0de87bf7a45ff7416ecd967037fa0b -reef622da1b387cfd1dd68babeb0bfecfbae5caa3 --- library/lib/xotcl1.xotcl (.../xotcl1.xotcl) (revision e5b7b9261b0de87bf7a45ff7416ecd967037fa0b) +++ library/lib/xotcl1.xotcl (.../xotcl1.xotcl) (revision eef622da1b387cfd1dd68babeb0bfecfbae5caa3) @@ -73,7 +73,7 @@ Class instproc unknown {args} { #puts stderr "use '[self] create $args', not '[self] $args'" - eval my create $args + uplevel [list [self] create {*}$args] } Object instproc unknown {m args} { @@ -228,13 +228,8 @@ # info nonposargs # info default # - # => TODO: use "params" in serializer, and all other occurances - # - # # TODO mark all absolete calls at least as deprecated in library # - # TODO move unknown handler for Class into a library - # proc ::xotcl::info_args {allocation o method} { set result [list] Index: library/serialize/Serializer.xotcl =================================================================== diff -u -r663e30c8870734f62fcb9b5491b68eca06f2b295 -reef622da1b387cfd1dd68babeb0bfecfbae5caa3 --- library/serialize/Serializer.xotcl (.../Serializer.xotcl) (revision 663e30c8870734f62fcb9b5491b68eca06f2b295) +++ library/serialize/Serializer.xotcl (.../Serializer.xotcl) (revision eef622da1b387cfd1dd68babeb0bfecfbae5caa3) @@ -533,7 +533,7 @@ foreach k [array names .exportMethods] { foreach {o p m} $k break if {![.methodExists $o $p $m]} { - $s warn "Method does not exists: $o $p $m" + $s warn "Method does not exist: $o $p $m" continue } append methods($o) [.serializeExportedMethod $o $p $m] Index: tests/mixinoftest.xotcl =================================================================== diff -u -r73eb4eccd33d1a940e2d2ca6dccc2f74216f0576 -reef622da1b387cfd1dd68babeb0bfecfbae5caa3 --- tests/mixinoftest.xotcl (.../mixinoftest.xotcl) (revision 73eb4eccd33d1a940e2d2ca6dccc2f74216f0576) +++ tests/mixinoftest.xotcl (.../mixinoftest.xotcl) (revision eef622da1b387cfd1dd68babeb0bfecfbae5caa3) @@ -477,3 +477,35 @@ #::xotcl::test::Test destroy #puts [lsort [::xotcl::Object allinstances]] +::xotcl::use xotcl2x +########################################### +# testing simple per object mixins +########################################### +Test case xotcl2-mixinof +Class create M +Class create A +Class create C +C create c1 -mixin A +C create c2 +? {c1 mixin} ::A +? {c1 info mixin} ::A +? {A info mixinof} ::c1 +? {M info mixinof} "" +C mixin M +? {M info mixinof} "::c1 ::c2" +? {M info mixinof -scope object} "" +? {M info mixinof -scope class} "::C" +? {A info mixinof} "::c1" +? {A info mixinof -scope object} "::c1" +? {A info mixinof -scope class} "" + +c1 destroy +? {A info mixinof} "" +? {M info mixinof} "::c2" +c2 destroy +? {M info mixinof} "" + +A destroy +C destroy +M destroy +