File: traits-simple.tcl

package info (click to toggle)
nsf 2.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 13,208 kB
  • sloc: ansic: 32,687; tcl: 10,723; sh: 660; pascal: 176; javascript: 135; lisp: 41; makefile: 24
file content (64 lines) | stat: -rw-r--r-- 2,077 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# Implementation study based on 
#
#   S. Ducasse, O. Nierstrasz, N. Schärli, R. Wuyts, A. Black:
#   Traits: A Mechanism for Fine-grained Reuse,
#   ACM transactions on Programming Language Systems, Vol 28, No 2, March 2006
#
# Example in Fig 12: ReadStream and Trait tReadStream
#
# In this example, traits are used to extend classes and other traits.

package require nx::test
package require nx::trait

#
# Create a simple trait called +tReadStream+ which provides the
# interface to a stream. In contrary to a composite trait, a simple
# trait does not inherit from another trait.
#
nx::Trait create tReadStream {
  #
  # Define the methods provided by this trait:
  #
  :public method atStart {} {expr {[:position get] == [:minPosition]}}
  :public method atEnd {} {expr {[:position get] == [:maxPosition]}}
  :public method setToStart {} {set :position [:minPosition]}
  :public method setToEnd {} {set :position [:maxPosition]}
  :public method maxPosition {} {llength ${:collection}}
  :public method on {collection} {set :collection $collection; :setToStart}
  :public method next {} {
    if {[:atEnd]} {return ""} else {
      set r [lindex ${:collection} ${:position}]
      :nextPosition
      return $r
    }
  }
  :public method minPosition {} {return 0}
  :public method nextPosition {} {incr :position 1}
  
  # This trait requires a method "position" and a variable
  # "collection" from the base class. The definition is incomplete in
  # these regards.

  :requiredMethods position
  :requiredVariables collection
}

# Define the class +ReadStream+ with properties +position+ and
# +collection+ that uses the trait. The method +require trait+ checks the
# requirements of the trait and imports the methods into +ReadStream+.

nx::Class create ReadStream {
  :property {collection ""}
  :property -accessor public {position 0}
  :require trait tReadStream
}

# Create an instance of the class +ReadStream+:
ReadStream create r1 -collection {a b c d e}

# Test the behavior of the composed class:
? {r1 atStart} 1
? {r1 atEnd} 0
? {r1 next} a
? {r1 next} b