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} + + # Use the trait "TPositionableStream" + :useTrait 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} + + # Use the trait "TPositionableStream" + :useTrait TPositionableStream +}
Define a class ReadStream with properties position and +collection that uses the composite trait TReadStream:
nx::Class create ReadStream { + :property {collection ""} + :property {position 0} + :useTrait 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