Index: doc/example-scripts/bagel.html =================================================================== diff -u -r24cb8f4bffd49c9375c1c64aa0610933b62511bb -rc4f449cb353be812ba6502ef8e9587e87881f59b --- doc/example-scripts/bagel.html (.../bagel.html) (revision 24cb8f4bffd49c9375c1c64aa0610933b62511bb) +++ doc/example-scripts/bagel.html (.../bagel.html) (revision c4f449cb353be812ba6502ef8e9587e87881f59b) @@ -1,1117 +1,1117 @@ - - - - - -Listing of doc/example-scripts/bagel.tcl - - - - - -
-
-
-

This example is a straight translation of the OTcl Tutorial -http://www.isi.edu/nsnam/otcl/doc/tutorial.html to NX. It serves as -a very short intro to the basic elements of scripting with NX and -provides a comparison study to OTcl.

-
-
-
package req nx
-nx::test configure -count 1
-

Suppose we need to work with many bagels in our application. We -might start by creating a Bagel class.

-
-
-
% nx::Class create Bagel
-::Bagel
-

We can now create bagels and keep track of them using the info -method.

-
-
-
% Bagel create abagel
-::abagel
-
-% abagel info class
-::Bagel
-
-% Bagel info instances
-::abagel
-

Of course, bagels don’t do much yet. They should remember whether -they’ve been toasted. We can create and access an instance variable -by defining an property for the class. All instance variables are -per default public in the sense of C++.

-
-
-
% Bagel property {toasted 0}
-

Since abagel was created before the definition of the property we -have to set the default value for it using the setter method. Again, -the info method helps us keep track of things.

-
-
-
% abagel info vars
-
-% abagel configure -toasted 0
-
-% abagel info vars
-toasted
-
-% abagel cget -toasted
-0
-

But we really want them to begin in an untoasted state to start -with.

-
-
-
% Bagel create bagel2
-::bagel2
-
-% bagel2 info vars
-toasted
-
-% bagel2 cget -toasted
-0
-

Our bagels now remember whether they’ve been toasted. Let is -recreate the first one.

-
-
-
% lsort [Bagel info instances]
-::abagel ::bagel2
-
-% ::abagel destroy
-
-% Bagel info instances
-::bagel2
-
-% Bagel create abagel
-::abagel
-

Now we’re ready to add a method to bagels so that we can toast -them. Methods have an argument list and body like regular -Tcl procs. Here’s the toast method.

-
-
-
% Bagel public method toast {} {
-      if {[incr :toasted] > 1} then {
-        error "something's burning!"
-      }
-}
-::nsf::classes::Bagel::toast
-

The defined methods can be queried with info. We see as well the -setter method for the variable toasted.

-
-
-
% Bagel info methods
-toast
-

Aside from setting the toasted variable, the body of the toast -method demonstrates how to access instance variables by using a -leading colon in the name.

-

We invoke the toast method on bagels in the same way we use the -info and destroy methods that were provided by the system. That -is, there is no distinction between user and system methods.

-
-
-
% abagel toast
-% abagel toast
-something's burning!
-

Now we can add spreads to the bagels and start tasting them. If we -have bagels that aren’t topped, as well as bagels that are, we may -want to make toppable bagels a separate class. Let explore -inheritance with these two classes, starting by making a new class -SpreadableBagel that inherits from Bagel. A SpreadableBagel has an -property toppings which might have multiple values. Initially, -toppings are empty.

-
-
-
% nx::Class create SpreadableBagel -superclass Bagel {
-    :property -incremental {toppings:0..n ""}
-}
-::SpreadableBagel
-
-% SpreadableBagel cget -superclass
-::Bagel
-% SpreadableBagel info superclasses
-::Bagel
-
-% SpreadableBagel info heritage
-::Bagel ::nx::Object
-

Let’s add a taste method to bagels, splitting its functionality -between the two classes and combining it with next.

-
-
-
% Bagel public method taste {} {
-    if {${:toasted} == 0} then {
-    return raw!
-  } elseif {${:toasted} == 1} then {
-    return toasty
-  } else {
-    return burnt!
-  }
-}
-::nsf::classes::Bagel::taste
-
-% SpreadableBagel public method taste {} {
-    set t [next]
-    foreach i ${:toppings} {
-       lappend t $i
-    }
-    return $t
-}
-::nsf::classes::SpreadableBagel::taste
-
-% SpreadableBagel create abagel
-::abagel
-
-% abagel toast
-% abagel toppings add jam
-jam
-% abagel toppings add m&m
-m&m jam
-
-% abagel taste
-toasty m&m jam
-

Of course, along come sesame, onion, poppy, and a host of other -bagels, requiring us to expand our scheme. We could keep track of -flavor with an instance variable, but this may not be -appropriate. Flavor is an innate property of the bagels, and one -that can affect other behavior - you wouldn’t put jam on an onion -bagel, would you? Instead of making a class hierarchy, let’s use -multiple inheritance to make the flavor classes mixins that add a -their taste independent trait to bagels or whatever other food they -are mixed with.

-
-
-
% nx::Class create Sesame {
-    :public method taste {} {concat [next] "sesame"}
-}
-::Sesame
-
-% nx::Class create Onion {
-    :public method taste {} {concat [next] "onion"}
-}
-::Onion
-
-% nx::Class create Poppy {
-    :public method taste {} {concat [next] "poppy"}
-}
-::Poppy
-

Well, they don’t appear to do much, but the use of next allows them -to be freely mixed.

-
-
-
% nx::Class create SesameOnionBagel -superclass SpreadableBagel -mixin {Sesame Onion}
-::SesameOnionBagel
-
-% SesameOnionBagel create abagel -toppings butter
-::abagel
-
-% abagel taste
-raw! butter onion sesame
-

For multiple inheritance, the system determines a linear inheritance -ordering that respects all of the local superclass orderings. You -can examine this ordering with an info option. next follows this -ordering when it combines behavior.

-
-
-
% SesameOnionBagel info heritage
-::Sesame ::Onion ::SpreadableBagel ::Bagel ::nx::Object
-
-% abagel info precedence
-::Sesame ::Onion ::SesameOnionBagel ::SpreadableBagel ::Bagel ::nx::Object
-

We can also combine our mixins with other classes, classes that need -have nothing to do with bagels, leading to a family of chips.

-
-
-
% nx::Class create Chips {
-    :public method taste {} {return "crunchy"}
-}
-::Chips
-
-% nx::Class create OnionChips -superclass Chips -mixin Onion
-::OnionChips
-
-% OnionChips create abag
-::abag
-
-% abag taste
-crunchy onion
-
-
-
-

- - - + + + + + +Listing of doc/example-scripts/bagel.tcl + + + + + +
+
+
+

This example is a straight translation of the OTcl Tutorial +http://www.isi.edu/nsnam/otcl/doc/tutorial.html to NX. It serves as +a very short intro to the basic elements of scripting with NX and +provides a comparison study to OTcl.

+
+
+
package req nx
+nx::test configure -count 1
+

Suppose we need to work with many bagels in our application. We +might start by creating a Bagel class.

+
+
+
% nx::Class create Bagel
+::Bagel
+

We can now create bagels and keep track of them using the info +method.

+
+
+
% Bagel create abagel
+::abagel
+
+% abagel info class
+::Bagel
+
+% Bagel info instances
+::abagel
+

Of course, bagels don’t do much yet. They should remember whether +they’ve been toasted. We can create and access an instance variable +by defining an property for the class. All instance variables are +per default public in the sense of C++.

+
+
+
% Bagel property {toasted 0}
+

Since abagel was created before the definition of the property we +have to set the default value for it using the setter method. Again, +the info method helps us keep track of things.

+
+
+
% abagel info vars
+
+% abagel configure -toasted 0
+
+% abagel info vars
+toasted
+
+% abagel cget -toasted
+0
+

But we really want them to begin in an untoasted state to start +with.

+
+
+
% Bagel create bagel2
+::bagel2
+
+% bagel2 info vars
+toasted
+
+% bagel2 cget -toasted
+0
+

Our bagels now remember whether they’ve been toasted. Let is +recreate the first one.

+
+
+
% lsort [Bagel info instances]
+::abagel ::bagel2
+
+% ::abagel destroy
+
+% Bagel info instances
+::bagel2
+
+% Bagel create abagel
+::abagel
+

Now we’re ready to add a method to bagels so that we can toast +them. Methods have an argument list and body like regular +Tcl procs. Here’s the toast method.

+
+
+
% Bagel public method toast {} {
+      if {[incr :toasted] > 1} then {
+        error "something's burning!"
+      }
+}
+::nsf::classes::Bagel::toast
+

The defined methods can be queried with info. We see as well the +setter method for the variable toasted.

+
+
+
% Bagel info methods
+toast
+

Aside from setting the toasted variable, the body of the toast +method demonstrates how to access instance variables by using a +leading colon in the name.

+

We invoke the toast method on bagels in the same way we use the +info and destroy methods that were provided by the system. That +is, there is no distinction between user and system methods.

+
+
+
% abagel toast
+% abagel toast
+something's burning!
+

Now we can add spreads to the bagels and start tasting them. If we +have bagels that aren’t topped, as well as bagels that are, we may +want to make toppable bagels a separate class. Let explore +inheritance with these two classes, starting by making a new class +SpreadableBagel that inherits from Bagel. A SpreadableBagel has an +property toppings which might have multiple values. Initially, +toppings are empty.

+
+
+
% nx::Class create SpreadableBagel -superclass Bagel {
+    :property -incremental {toppings:0..n ""}
+}
+::SpreadableBagel
+
+% SpreadableBagel cget -superclass
+::Bagel
+% SpreadableBagel info superclasses
+::Bagel
+
+% SpreadableBagel info heritage
+::Bagel ::nx::Object
+

Let’s add a taste method to bagels, splitting its functionality +between the two classes and combining it with next.

+
+
+
% Bagel public method taste {} {
+    if {${:toasted} == 0} then {
+    return raw!
+  } elseif {${:toasted} == 1} then {
+    return toasty
+  } else {
+    return burnt!
+  }
+}
+::nsf::classes::Bagel::taste
+
+% SpreadableBagel public method taste {} {
+    set t [next]
+    foreach i ${:toppings} {
+       lappend t $i
+    }
+    return $t
+}
+::nsf::classes::SpreadableBagel::taste
+
+% SpreadableBagel create abagel
+::abagel
+
+% abagel toast
+% abagel toppings add jam
+jam
+% abagel toppings add m&m
+m&m jam
+
+% abagel taste
+toasty m&m jam
+

Of course, along come sesame, onion, poppy, and a host of other +bagels, requiring us to expand our scheme. We could keep track of +flavor with an instance variable, but this may not be +appropriate. Flavor is an innate property of the bagels, and one +that can affect other behavior - you wouldn’t put jam on an onion +bagel, would you? Instead of making a class hierarchy, let’s use +multiple inheritance to make the flavor classes mixins that add a +their taste independent trait to bagels or whatever other food they +are mixed with.

+
+
+
% nx::Class create Sesame {
+    :public method taste {} {concat [next] "sesame"}
+}
+::Sesame
+
+% nx::Class create Onion {
+    :public method taste {} {concat [next] "onion"}
+}
+::Onion
+
+% nx::Class create Poppy {
+    :public method taste {} {concat [next] "poppy"}
+}
+::Poppy
+

Well, they don’t appear to do much, but the use of next allows them +to be freely mixed.

+
+
+
% nx::Class create SesameOnionBagel -superclass SpreadableBagel -mixin {Sesame Onion}
+::SesameOnionBagel
+
+% SesameOnionBagel create abagel -toppings butter
+::abagel
+
+% abagel taste
+raw! butter onion sesame
+

For multiple inheritance, the system determines a linear inheritance +ordering that respects all of the local superclass orderings. You +can examine this ordering with an info option. next follows this +ordering when it combines behavior.

+
+
+
% SesameOnionBagel info heritage
+::Sesame ::Onion ::SpreadableBagel ::Bagel ::nx::Object
+
+% abagel info precedence
+::Sesame ::Onion ::SesameOnionBagel ::SpreadableBagel ::Bagel ::nx::Object
+

We can also combine our mixins with other classes, classes that need +have nothing to do with bagels, leading to a family of chips.

+
+
+
% nx::Class create Chips {
+    :public method taste {} {return "crunchy"}
+}
+::Chips
+
+% nx::Class create OnionChips -superclass Chips -mixin Onion
+::OnionChips
+
+% OnionChips create abag
+::abag
+
+% abag taste
+crunchy onion
+
+
+
+

+ + +