<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>Migration Guide from XOTcl to the Next Scripting Language</title> <style> body { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: normal; background-color : white; color: black; } table i { font-size: 80%; } table td code i { font-style: italic; color: green; } pre i { font-style: italic; color: green; } th {color: #888888;} td hr { color: #FFFFFF; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: dashed; border-color: #AAAAAA; margin: 10 10 10 10; } /*table {font-size: 80%;}*/ table { width: 900; border-collapse:collapse; } table th { width: 400; border:1px solid black; } table td { width: 400; padding: 10px; border:1px solid #AAAAAA; } </style> </head> <body> <h1>Introduction</h1> ... general text, maybe partly from slides/paper .... TODO: I think, we should not use ::nx::core, but import "needed" commands into ::nx. <h2>Supporting XOTcl 1 in Next</h2> <p> In general, the Next 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, Next supports primarily XOTcl and the Next scripting language (XOTcl provides about twice as many predefined builtin methods compared to Next). </p> <p> A single Tcl interpreter can host both, XOTcl and the Next scripting language at the same time. This makes migration from XOTcl to Next easier. The following example script shows to use in a single XOTcl and Next<p> <pre> namespace eval mypackage { package require XOTcl <i># Import XOTcl into the current namespace</i> namespace import -force ::xotcl::* <i># Define a class using XOTcl</i> Class C1 C1 instproc foo {} {puts "hello world"} <i># Import Next into the current namespace</i> namespace import -force ::nx::* <i># Define a class using Next</i> Class create C2 { :method foo {} {puts "hello world"} } } </pre> <p> "Switching" between XOTcl and Next effectively means the load some libraries if needed and to import either the base classes (<code>Object</code> and <code>Class</code>) of XOTcl or Next into the current namespace. </p> <h1>XOTcl Idioms in the Next scripting language</h1> <h2>Defining Objects and Classes</h2> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code>Class <i>ClassName</i></code></td> <td><code>Class create <i>ClassName</i></code></td> </tr> <tr> <td><code>Object <i>ObjectName</i></code></td> <td><code>Object create <i>ObjectName</i></code></td> </tr> <tr> <td><code>::xotcl::Class <i>ClassName</i></code></td> <td><code>::nx::Class create <i>ClassName</i></code></td> </tr> <tr> <td><code>::xotcl::Object <i>ObjectName</i></code></td> <td><code>::nx::Object create <i>ObjectName</i></code></td> </tr> </table> <h2>Defining Methods</h2> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code>Class <i>C</i><br> <i>C</i> instproc <i>foo args</i> {...}<br> <i>C</i> proc <i>bar args</i> {...}<br> </code></td> <td><code>Class create <i>C</i> {<br> :method <i>foo args</i> {...}<br> :object method <i>bar args</i> {...}<br> }<br></code><hr> <code>Class create <i>C</i><br> <i>C</i> method <i>foo args</i> {...}<br> <i>C</i> object method <i>bar args</i> {...}<br> </code></td> </tr> <tr> <td><code>Object <i>o</i><br> <i>o</i> set <i>x 1</i><br> <i>o</i> proc <i>foo args</i> {...}<br> </code></td> <td><code>Object create <i>o</i> {<br> set :<i>x 1</i><br> :method <i>foo args</i> {...}<br> }<br></code><hr> <code>Object create <i>o</i><br> <i>o</i> eval {set <i>:x 1</i>}</i><br> <i># ::nx::core::setvar o x 1</i><br> <i>o</i> method <i>foo args</i> {...}<br> </code></td> </tr> </table> <h2>Resolvers</h2> Next 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 Next resolvers are used in the XOTcl environment as well. <h2>Invoking Methods</h2> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code>Class <i>C</i><br> <i>C</i> instproc <i>foo args</i> {...}<br> <i>C</i> instproc <i>bar args</i> {<br> my <i>foo 1 2 3</i> ;# invoke own method<br> <i>o baz</i> ;# invoke others method<br> }<br> Object <i>o</i><br> <i>o</i> proc <i>baz</i> {} {...}<br> </code></td> <td><code>Class create <i>C</i> {<br> :method <i>foo args</i> {...}<br> :method <i>bar args</i> {<br> :<i>foo 1 2 3</i> ;# invoke own method<br> <i>o baz</i> ;# invoke others method<br> }<br> }</br> Object create <i>o</i> {<br> :method <i>baz</i> {} {...}<br> }</br> </code></td> </tr> </table> <h2>Accessing Instance Variables from Method Bodies</h2> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code>Class <i>C</i><br> <i>C</i> instproc <i>foo args</i> {<br> <i># method scoped variable a</i><br> set a 1 <br> <i># instance variable b</i><br> my instvar b<br> set b 2<br> <i># global variable/namespaced variable c</i><br> set ::c 3<br> }<br> </code></td> <td><code>Class create <i>C</i> {<br> :method <i>foo args</i> {...}<br> <i># method scoped variable a</i><br> set a 1 <br> <i># instance variable b</i><br> set :b 2<br> <i># global variable/namespaced variable c</i><br> set ::c 3<br> }<br> }<br> </code></td> </tr> <tr> <td><code>my set <i>varname value</i></code></td> <td><code>set :<i>varname value</i></code></td> </tr> <tr> <td><code>set <i>newVar</i> [my set <i>otherVar</i>]</code></td> <td><code>set <i>newVar</i> [set <i>:otherVar</i>]</code><br><hr> <code>set <i>newVar</i> ${:otherVar}</i></code><br> </td> </tr> <tr> <td><code>my instvar <i>newVar</i><br> set <i>newVar value</i> </code> </td> <td><code>set <i>:newVar value</i></td> </tr> <tr> <td><code>my exists <i>varname</i></code></td> <td><code>info :<i>varname</i></code></td> </tr> </table> <h2>Accessing Instance Variables of other Objects</h2> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> set <i>varname value</i></code></td> <td><code><i>obj</i> eval [list set <i>:varname value</i>]</code></td> </tr> <tr> <td><code>set <i>newVar</i> [<i>obj</i> set <i>otherVar</i>]</code></td> <td><code>set <i>newVar</i> [<i>obj</i> eval {set <i>:otherVar</i>}]</code><br> </td> </tr> <tr> <td><code><i>obj</i> instvar <i>newVar</i><br> set <i>newVar value</i> </code> </td> <td><code>::nx::core::importvar <i>obj newVar</i><br> set <i>newVar value</i></td> </tr> <tr> <td><code><i>obj</i> exists <i>varname</i></code></td> <td><code><i>obj</i> eval {info exists <i>:varname</i>}</code></td> </tr> </table> <h2>Object Parameters</h2> <h2>Method Parameters</h2> <h2>Introspection</h2> <h4>List methods defined by objects</h4> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> info commands <i>?pattern?</i></code></td> <td><code><i>obj</i> info methods <i>?pattern?</i></code></td> </tr> <tr> <td><code><i>obj</i> info parametercmd <i>?pattern?</i></code></td> <td><code><i>obj</i> info methods -methodtype setter <i>?pattern?</i></code></td> </tr> <tr> <td><code><i>obj</i> info procs <i>?pattern?</i></code></td> <td><code><i>obj</i> info methods -methodtype scripted <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info methods -methodtype alias <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info methods -methodtype forwarder <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info methods -methodtype object <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info methods -callprotection <i>public|protected ...</i></code></td> </tr> </table> <h4>List methods defined by classes</h4> <table> <tr> <td><code><i>cls</i> info instcommands <i>?pattern?</i></code></td> <td><code><i>cls</i> info methods <i>?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info instparametercmd <i>?pattern?</i></code></td> <td><code><i>cls</i> info methods -methodtype setter <i>?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info instprocs <i>?pattern?</i></code></td> <td><code><i>cls</i> info methods -methodtype scripted <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> info methods -methodtype alias <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> info methods -methodtype forwarder <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> info methods -methodtype object <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> info methods -callprotection <i>public|protected ...</i></code></td> </tr> </table> <h4>List class object specific methods</h4> <table> <tr> <td><code><i>cls</i> info commands <i>?pattern?</i></code></td> <td><code><i>cls</i> object info methods <i>?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info parametercmd <i>?pattern?</i></code></td> <td><code><i>cls</i> object info methods -methodtype setter <i>?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info procs <i>?pattern?</i></code></td> <td><code><i>cls</i> object info methods -methodtype scripted <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> object info methods -methodtype alias <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> object info methods -methodtype forwarder <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> object info methods -methodtype object <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> object info methods -callprotection <i>public|protected ...</i></code></td> </tr> </table> <h4>List callable methods</h4> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> info methods <i>?pattern?</i></code></td> <td><code><i>obj</i> info callable <i>?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i># list only application specific methods</i></code><br> <code><i>obj</i> info callable -application</code></td> </tr> </table> <h4>List object/class where some method is defined</h4> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> procsearch <i>methodName</i></code></td> <td><code><i>obj</i> info callable -which <i>methodName</i></code></td> </tr> </table> <h4>List definition of scripted methods defined by classes</h4> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>cls</i> info instbody <i>methodName</i></code></td> <td><code><i>cls</i> info method body <i>methodName</i></code></td> </tr> <tr> <td><code><i>cls</i> info instargs <i>methodName</i></code></td> <td><code><i>cls</i> info method args <i>methodName</i></code></td> </tr> <tr> <td><code><i>cls</i> info instnonposargs <i>methodName</i></code></td> <td><code><i>cls</i> info method parameter <i>methodName</i></code></td> </tr> <tr> <td><code><i>cls</i> info instdefault <i>methodName</i></code></td> <td><code><i>cls</i> info method parameter <i>methodName</i></code></td> </tr> <tr> <td><code><i>cls</i> info instpre <i>methodName</i></code></td> <td><code><i>cls</i> info method precondition <i>methodName</i></code></td> </tr> <tr> <td><code><i>cls</i> info instpost <i>methodName</i></code></td> <td><code><i>cls</i> info method postcondition <i>methodName</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> info method definition <i>methodName</i></code></td> </tr> </table> <h4>List definition of scripted object specific methods</h4> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> info body <i>methodName</i></code></td> <td><code><i>obj</i> info method body <i>methodName</i></code></td> </tr> <tr> <td><code><i>obj</i> info args <i>methodName</i></code></td> <td><code><i>obj</i> info method args <i>methodName</i></code></td> </tr> <tr> <td><code><i>obj</i> info nonposargs <i>methodName</i></code></td> <td><code><i>obj</i> info method parameter <i>methodName</i></code></td> </tr> <tr> <td><code><i>obj</i> info default <i>methodName</i></code></td> <td><code><i>obj</i> info method parameter <i>methodName</i></code></td> </tr> <tr> <td><code><i>obj</i> info pre <i>methodName</i></code></td> <td><code><i>obj</i> info method precondition <i>methodName</i></code></td> </tr> <tr> <td><code><i>obj</i> info post <i>methodName</i></code></td> <td><code><i>obj</i> info method postcondition <i>methodName</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info method definition <i>methodName</i></code></td> </tr> </table> <p>For definition of class object specific methods, use modifier <code>object</code> as shown in examples above. </p> <h4>List filter or mixins</h4> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> info filter <i>?-order? ?-guards? ?pattern?</i></code></td> <td><code><i>obj</i> info filter <i>?-order? ?-guards? ?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info filter <i>?-order? ?-guards? ?pattern?</i></code></td> <td><code><i>cls</i> object info filter <i>?-order? ?-guards? ?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info instfilter <i>?-order? ?-guards? ?pattern?</i></code></td> <td><code><i>cls</i> info filter <i>?-order? ?-guards? ?pattern?</i></code></td> </tr> <tr> <td><code><i>obj</i> info mixin <i>?-order? ?-guards? ?pattern?</i></code></td> <td><code><i>obj</i> info mixin <i>?-order? ?-guards? ?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info mixin <i>?-order? ?-guards? ?pattern?</i></code></td> <td><code><i>cls</i> object info mixin <i>?-order? ?-guards? ?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info instmixin <i>?-order? ?-guards? ?pattern?</i></code></td> <td><code><i>cls</i> info mixin <i>?-order? ?-guards? ?pattern?</i></code></td> </tr> </table> <h4>List definition of methods defined by aliases, setters or forwarders</h4> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info method definition <i>methodName</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls ?object?</i> info method definition <i>methodName</i></code></td> </tr> </table> <h4>List fully qualified name of method</h4> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info method name <i>methodName</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls ?object?</i> info method name <i>methodName</i></code></td> </tr> </table> <h4>List type of a method</h4> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><i>n.a.</i></td> <td><code><i>obj</i> info method type <i>methodName</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls ?object?</i> info method type <i>methodName</i></code></td> </tr> </table> <h4>List the scope of mixin classes</h4> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>cls</i> info mixinof <i>?-closure? ?pattern?</i></code></td> <td><code><i>cls</i> info mixinof -scope object <i>?-closure? ?pattern?</i></code></td> </tr> <tr> <td><code><i>cls</i> info instmixinof <i>?-closure? ?pattern?</i></code></td> <td><code><i>cls</i> info mixinof -scope class <i>?-closure? ?pattern?</i></code></td> </tr> <tr> <td><i>n.a.</i></td> <td><code><i>cls</i> info mixinof -scope all <i>?-closure? ?pattern?</i></code></td> </tr> </table> <h4>Check properties of object and classes</h4> <table> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> istype <i>sometype</i></code></td> <td> TODO: ::nx::core::objectproperty and/or ::nx::objectproperty and/or nx::is?<p> <code>::nx::core::objectproperty <i>obj</i> type <i>sometype</i></code><br> <hr> <code><i>obj</i> info is type <i>sometype</i></code> </td> </tr> <tr> <td><code><i>obj</i> ismixin <i>cls</i></code></td> <td> <code>::nx::core::objectproperty <i>obj</i> mixin <i>cls</i></code><br> <hr> <code><i>obj</i> info is mixin <i>cls</i></code> </td> </tr> <tr> <td><code><i>obj</i> isclass <i>?cls?</i></code></td> <td> <code>::nx::core::objectproperty <i>obj|cls</i> class</code><br> <hr> <code><i>obj</i> info is class</code> </td> </tr> <tr> <td><code><i>obj</i> ismetaclass <i>cls</i></code></td> <td><code>::nx::core::objectproperty <i>obj|cls</i> metaclass</code> <hr> <code><i>obj</i> info is metaclass</code> </td> </tr> <tr> <td><i>n.a.</i></td> <td><code>::nx::core::objectproperty <i>cls</i> baseclass</code> <hr> <code><i>cls</i> info is baseclass</code> </td> </tr> <tr> <td><code><i>obj</i> isobject <i>obj2</i></code></td> <td><code>::nx::core::objectproperty <i>obj|obj2</i> object</code> <hr> <code><i>obj</i> info is object</code> </td> </tr> </table> <h2>Predefined Methods</h2> <h2>Dispatch, Aliases, etc.</h2> <h2>Assertions</h2> <table border=1> <tr><th>XOTcl</th><th>Next</th></tr> <tr> <td><code><i>obj</i> check <i>checkptions</i></code></td> <td><code>::nx::core::assertion <i>obj</i> check <i>checkptions</i></code></td> </tr> <tr> <td><code><i>obj</i> info check</code></td> <td><code>::nx::core::assertion <i>obj</i> check</code></td> </tr> <tr> <td><code><i>obj</i> invar <i>conditions</i></code></td> <td><code>::nx::core::assertion <i>obj</i> object-invar <i>conditions</i></code></td> </tr> <tr> <td><code><i>obj</i> info invar</code></td> <td><code>::nx::core::assertion <i>obj</i> object-invar</code></td> </tr> <tr> <td><code><i>cls</i> instinvar <i>conditions</i></code></td> <td><code>::nx::core::assertion <i>cls</i> class-invar <i>conditions</i></code></td> </tr> <tr> <td><code><i>cls</i> info instinvar</code></td> <td><code>::nx::core::assertion <i>cls</i> class-invar</code></td> </tr> <tr> <td><code><i>cls</i> invar <i>conditions</i></code></td> <td><code>::nx::core::assertion <i>cls</i> object-invar <i>conditions</i></code></td> </tr> <tr> <td><code><i>cls</i> info invar</code></td> <td><code>::nx::core::assertion <i>cls</i> object-invar</code></td> </tr </table> <h2>Method Protection</h2> <h2>Incompatibilities</h2> <h3>Namespace resolvers</h3> <p>The Next namespace resolvers are use as well when XOTcl is used within Next. </p> <h3>Stronger Checking</h3> <p>Next performs stronger checking than XOTcl. The requiredness of slots in XOTcl was just a comment, while Next enforces it. </p> <h3>Different results</h3> <ul> <li><code>[self next]</code> returns <br> instead of "proc" and "instproc" => "method"<br> instead of "parametercmd" and "instparametercmd" => "setter"<br> instead of "instforward" => "forward"<br> instead of "instcmd" => "cmd".<br> The modifier "object" is added when needed. </li> <li><code>[self filterreg]</code> returns <br> instead of "instforward" => "forward"<br> The modifier "object" is added when needed. </li> </ul> <h3>Exit handlers</h3> <p> The exit hander interface changed from a method of <code>::xotcl::Object</code> into procs in the <code>::nx::core</code> namespace. Next provides now: <pre> ::nx::core::setExitHandler script ::nx::core::getExitHandler ::nx::core::unsetExitHandler </pre> <hr> <address></address> <!-- hhmts start --> Last modified: Tue May 25 14:00:20 CEST 2010 <!-- hhmts end --> </body> </html>