Listing of doc/example-scripts/traits-composite.tcl
Implementation study based on
-
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
Fig 13: tReadStream and tWriteStream as composite traits
In this example, traits are used to extend classes and other traits (called then composite traits).
package req nx::trait
Create a Trait called tPositionableStream
nx::Trait create tPositionableStream { # # 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 minPosition {} {return 0} :public method nextPosition {} {incr :position 1} # The trait requires a method "position" and a variable "collection" # from the base class or other traits. The definition is incomplete # in these regards :requiredMethods position :requiredVariables collection }
Create a composite trait called tReadStream
based on the trait
tPositionableStream
:
nx::Trait create tReadStream { # # Methods provided by this trait: # :public method on {collection} {set :collection $collection; :setToStart} :public method next {} { if {[:atEnd]} {return ""} else { set r [lindex ${:collection} ${:position}] :nextPosition return $r } } # This trait requires these methods: :requiredMethods {setToStart atEnd nextPosition} # Require the trait "tPositionableStream" :require trait tPositionableStream }
Create a composite trait called tWriteStream
based on the trait
tPositionableStream
:
nx::Trait create tWriteStream { # # Methods provided by this trait: # :public method on {collection} {set :collection $collection; :setToEnd} :public method nextPut {element} { lappend :collection $element :nextPosition return "" } # This trait requires these methods: :requiredMethods {setToEnd nextPosition} # Require the trait "tPositionableStream" :require trait tPositionableStream }
Define a class ReadStream
with properties position
and
collection
that uses the composite trait tReadStream
:
nx::Class create ReadStream { :property {collection ""} :property -accessor public {position 0} :require trait tReadStream }
Create an instance of 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