jima 30 Sep 2005: Some notes on the code.
- I really like tcl but perhaps I am leaping too far at giving names to things, I know I don't use the usual coding standard. I am actually trying to develop a coding standard of my own where every identifier (apart from those coming from other codes or language reserved keywords) has a built-in grammar.
- Here, on naming issues, I differ a lot from Artur Trzewik :)
- To as a prefix to denote function.
- Ab as a prefix to denote Class.
- Ar as a prefix to denote argument.
- Gl as a prefix to denote global variable.
- My as a prefix to denote member attribute.
- Th as a prefix to denote local variable.
jima 30 Sep 2005: The code (at a very early stage):
#<
#~ **Traits.tcl**.
#
#Trying to implement traits on top of **Xotcl**.
#>
package require XOTcl
namespace import -force ::xotcl::*
#<
#~~ Class **AbTraitable**.
#
#Classes that want to have traits have to belong to this metaclass.
#
#I don't know if the desirable order of calls is achieved this way.
#
#But I believe it is so.
#
#An alternative is to use the superclass scheme in order to guarantee that:
#
#* Class methods take precedence over trait methods.
#
#* Trait methods take precedence over superclass methods.
#>
Class AbTraitable -superclass Class
#<
#~~~ Method **ToUseTrait**.
#
#Given the name of a trait the traitable class will adopt it.
#
#It will do so unless there is a conflict.
#
#Then something must be done (to do).
#
#User will have to resolv the conflict.
#>
AbTraitable instproc ToUseTrait {
ArTraitName
} {
#Invokation of ToCheckTraitComposition to do.
#If everything goes fine.
#Remember that [self] here is a class.
foreach ThMethodName [$ArTraitName set MyMethodS] {
[self] instforward $ThMethodName -objscope $ThMethodName
}
}
#<
#~~~ Method **ToRemTrait**.
#
#Given the name of a trait the traitable class will remove it.
#>
AbTraitable instproc ToRemTrait {
ArTraitName
} {
set ThPos [lsearch -exact [my set MyTraitS] $ArTraitName]
if {[expr {$ThPos >= 0}]} {
#Remember that [self] here is a class.
foreach ThMethodName [$ArTraitName set MyMethodS] {
[self] instforward $ThMethodName
}
lreplace [my set MyTraitS] $ThPos $ThPos
}
}
#<
#~~ Class **AbTrait**.
#
#Here we go.
#>
Class AbTrait
#<
#~~~ Constructor.
#>
AbTrait instproc init {
} {
my set MyMethodS [list]
}
#<
#~~~ Method **ToAddMethod**.
#
#Given a method name add it to the trait.
#
#It will do so unless there is a conflict.
#
#Then an error method will be used in place.
#
#User will have to resolv the conflict.
#>
AbTrait instproc ToAddMethod {
ArMethodName
} {
set ThPos [lsearch -exact [my set MyMethodS] $ArMethodName]
if {[expr {$ThPos < 0}]} {
my lappend MyMethodS $ArMethodName
} else {
my ToAddError_Method $ArMethodName
}
}
#<
#~~~ Method **ToAddError_Method**.
#
#Given a method name add a corresponding error method to the trait.
#
#User will have to resolv the conflict.
#>
AbTrait instproc ToAddError_Method {
ArMethodName
} {
#To do.
}
#<
#~~~ Method **ToSubMethod**.
#
#Given a method name subtract it from the trait if it exists.
#>
AbTrait instproc ToSubMethod {
ArMethodName
} {
set ThPos [lsearch -exact [my set MyMethodS] $ArMethodName]
if {[expr {$ThPos >= 0}]} {
lreplace [my set MyMethodS] $ThPos $ThPos
}
}
#<
#~~~ Method **ToCompose5Trait**.
#
#Given a trait name compose the methods of self with those of the object.
#
#It will do so unless there is a conflict.
#
#Then an error method will be used in place.
#
#User will have to resolv the conflict.
#>
AbTrait instproc ToCompose5Trait {
ArTraitName
} {
#To do.
}
#<
#~~ Example.
#>
AbTraitable AbCircle\
-parameter {{MyCentre {100}}}\
-parameter {{MyRadius {100}}}\
-parameter {{MyColour {black}}}
proc ToRenameColour {
ArColour
} {
my set MyColour $ArColour
}
proc ToPutColour {
} {
puts "[self] is [my set MyColour] coloured."
}
AbTrait GlCircleTrait
GlCircleTrait ToAddMethod ToRenameColour
GlCircleTrait ToAddMethod ToPutColour
AbCircle ToUseTrait GlCircleTrait
AbCircle GlCircle
GlCircle ToPutColour
GlCircle ToRenameColour magenta
GlCircle ToPutColour
