# Listing of doc/example-scripts/traits-simple.tcl

Implementation study based on

1. 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::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] == [:minPosition]}}
      :public method atEnd {} {expr {[:position] == [: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