This is Peter's interface package at http://rrna.uia.ac.be/interface/ . Please have a look! I think we tcler's should adopt this methodolgy for packages. The following excerpts are taken from CLT.
# Example using interface package definition
package require interface
proc ::interfaces::stack-1.0 {option args} {
set interface stack
set version 1.0
switch $option {
interface {
# This is an interface defining object, so it supports the interface interface
# This code will advertise this fact
if {[llength $arg]} {
if {[string equal [lindex $args 0] interface]} {
return 0.8
} else {
error "::interfaces::$interface-$version does not support interface interface"
}
} else {
return [list interface 0.8]
}
}
doc {
# return xml documentation
return $::stackdock
}
test {
# run some tests on an object supposed to support the interface
set len [llength $args]
if {$len < 1} {
error "wrong # args: should be \"interfaces::$interface-$version test object ?options?\""
}
set object [lindex $args 0]
array set opt [lrange $args 1 end]
# the testleak is needed due to a small bug in the interface::test routine
set ::interface::testleak 0
interface::test {interface match} {
$object interface stack
} $version
interface::test {push and pop} {
$object clear
$object push 1
$object pop
} 1
interface::test {push, push and pop} {
$object clear
$object push 1
$object push 2
$object pop
} 2
interface::test {stack empty error} {
$object clear
$object pop
$object pop
} {stack empty} error
# more test should follow
interface::testend
}
}
}
# implementation of "object" implementing the interface
# this is of course just a test case for demonstrating interfaces,
# and not a real object, nor a good or even reasonable implementation
proc stack1 {option args} {
global stack1_data
switch $option {
clear {
set stack1_data {}
}
push {
eval lappend stack1_data $args
}
pop {
if {![llength $stack1_data]} {
error "stack empty"
}
set result [lindex $stack1_data end]
set stack1_data [lrange $stack1_data 0 end-1]
return $result
}
interface {
set interfaces {stack 1.0 nop 0.0}
if {[llength $args]} {
set reqinterface [lindex $args 0]
foreach {interface version} $interfaces {
if {[string equal $reqinterface $interface]} {
return $version
}
}
error "stack1 does not support interface $reqinterface"
} else {
return $interfaces
}
}
}
}
# test if stack1 does indeed comply with the stack-1.0 interface
interface test stack-1.0 stack1
# return documentation
interface doc stack-1.0
# It will usually be placed in a file in a doc directory, so it can also be
# used to generate man pages, etc
set stackdock {
stack_interface
description of the stack interface
DESCRIPTION
a very simple demonstration interface
THE STACK INTERFACE
objectName clear
clear the stack
objectName push value ?value ...?
push value(s) on the stack
objectName pop
get values from the stack
stack_interface
}
----
Wow !!! this is exactly what I was thinking of. Looks great !! Would
you consider this going into the tcllib ? I see the interface test is
not replacing a test package for the implementation object. Since the
interface namespace is a seperate both implementing procedures and
objects can implement it. It is not native inside the OO system so it
will work generically for everything. I am not too familiar with XML
yet. How would you render this documentation ? Maybe you could add to
the demo an implementation in some OO system or ask for others to
provide one for their OO system of choice.
* Of course I would not mind getting this in tcllib, but I have no idea how stuff gets in it.
* interface test is indeed not a replacement for a test package for the implementation object, but is meant to be used in one. An implementation can support several interfaces, so a typical test package will invoke interface test for all supported interfaces, and maybe add some tests specific to the object.
* The whole idea of the interface package is indeed to be as generic and implementation agnostic as possbile (cfr. the extremely simplified example)
* tmml (http://tmml.sourceforge.net/) contains some tools to convert the XML to man pages or html. (I got the CVS version)
art morel
----
Here is my initial cry for help where Peter replied with his solution:
I would like to be able to grab a script library/package that could be
implemented seperately in both tcl procedures and/or an object
orientated system such as itcl or all the others. Id like to define
the interface then be able to use whoevers package implements the
interface with their technology of choice. I haven't thought through
this very much but I think if we can cleanly define a interface, have
a standard so that many systems(snit,stoop,...) can be used to
implement the interface , and the interface User being able to handle
it(these drop in replacements), we will get more libraries of cool SW.
I have wrestled with a file buffer library for a little text editor of
mine. It started out as an library of routines to process/manage many
open buffers of text. It has lots of functions and was getting
unweildly. I next wrote it in itcl or base parts of it and it was much
slicker. I have not taken the time to integrate it into my old system
because it was not designed as a drop in replacement nor was the
application. Had I followed some standards I could have easily done
this. I suspect we all could get more code in our hands and offload
work to others if we some standards out there.
art
----
Larry Virden wrote:
Stuff gets into tcllib in at least two ways:
o someone who has written some software signs up to be a http://tcllib.sf.net
developer, talks to the other developers on the tcllib-dev mailing
list (to get points to guidelines, confirm namespace choices, etc.),
and then checks the code , etc. into the cvs
o someone who has written some software evangelizes someone already a tcllib
developer to do the work for them - or at least gets them
enthusiastic enough about the package that the newly recruited
convert does the work for the software creator.
According to Peter.DeRijk :
:- Of course I would not mind getting this in tcllib, but I have no idea
: how stuff gets in it.
----
Any takers to help get this package to sourceforge then into tcllib?
[http://68.6.44.242:8085/images/doesNotExist.jpg]
----