Index: library/lib/nx-traits.tcl =================================================================== diff -u -r8c8980c36802cc5e71f8a1713945e7655a5a480a -rd31c271afb2488abafa0642b07538a3e62106130 --- library/lib/nx-traits.tcl (.../nx-traits.tcl) (revision 8c8980c36802cc5e71f8a1713945e7655a5a480a) +++ library/lib/nx-traits.tcl (.../nx-traits.tcl) (revision d31c271afb2488abafa0642b07538a3e62106130) @@ -1,5 +1,5 @@ package require nx -package provide nx::trait 0.2 +package provide nx::trait 0.3 # @package nx::trait # @@ -39,6 +39,32 @@ # namespace eval ::nx::trait {} +# +# nx::trait::provide and nx::trait::require implement the basic +# loading mechanism for traits +# +nsf::proc nx::trait::provide {traitName script} { + set ::nsf::traitIndex($traitName) [list script $script] +} + +nsf::proc nx::trait::require {traitName} { + if {[::nsf::object::exists $traitName]} {return} + set key ::nsf::traitIndex($traitName) + if {[info exists $key]} { + array set "" [set $key] + if {$(script) ne ""} { + eval $(script) + + } + } + if {[::nsf::object::exists $traitName]} {return} + error "cannot require trait $traitName, trait unknown" +} + +# +# The function nx::trait::add adds the methods defined in the +# specified trait to the obj/class provided as first argument. +# nsf::proc nx::trait::add {obj -per-object:switch traitName {nameMap ""}} { array set map $nameMap foreach m [$traitName info methods -callprotection all] { @@ -54,6 +80,10 @@ } } +# +# The function nx::trait::checkObject checks, whether the target +# object has the method defined that the trait requires. +# nsf::proc nx::trait::checkObject {obj traitName} { foreach m [$traitName requiredMethods] { #puts "$m ok? [$obj info methods -closure $m]" @@ -62,6 +92,11 @@ } } } + +# +# The function nx::trait::checkClass checks, whether the target +# class has the method defined that the trait requires. +# nsf::proc nx::trait::checkClass {obj traitName} { foreach m [$traitName requiredMethods] { #puts "$m ok? [$obj info methods -closure $m]" @@ -71,31 +106,43 @@ } } +# +# The require methods for traits extend the predefined ensemble with +# trait-specific subcommands. +# nx::Class public method "require trait" {traitName {nameMap ""}} { # adding a trait to a class + nx::trait::require $traitName nx::trait::checkClass [self] $traitName nx::trait::add [self] $traitName $nameMap } nx::Class public method "require class trait" {traitName {nameMap ""}} { # adding a trait to the class object + nx::trait::require $traitName nx::trait::checkObject [self] $traitName nx::trait::add [self] -per-object $traitName $nameMap } nx::Object public method "require trait" {traitName {nameMap ""}} { # adding a trait to an object + nx::trait::require $traitName nx::traitCheckObject [self] $traitName nx::traitAdd [self] -per-object $traitName $nameMap } +# +# The class "nx::Trait" provides the basic properties and methods needed for +# the trait management. +# nx::Class create nx::Trait { - + :property {package} :property {requiredMethods:0..n,incremental ""} :property {requiredVariables:0..n,incremental ""} :public method "require trait" {traitName {nameMap ""}} { # adding a trait to a trait + nx::trait::require $traitName nx::trait::add [self] -per-object $traitName $nameMap set finalReqMethods {} foreach m [lsort -unique [concat ${:requiredMethods} [$traitName requiredMethods]]] {