Re: Xotcl and composition
- From: "Stéphane A." <sarnold@xxxxxxx>
- Date: Thu, 31 Jan 2008 08:46:43 -0800 (PST)
On 31 jan, 14:35, relaxmike <michael.bau...@xxxxxxxxx> wrote:
Hi all,
I am currently working on a project where I have to process
a workflow with several (scientific) executables. This workflow is
like a linear chain,
in which the output of the first software is the input of the 2nd
software.
I developped a Tcl script to process that workflow, with Tcl commands
in-between the
executables in order to create directories and set data files from one
executable
to the following one. It works fine, thanks to the simplicity of Tcl
for that kind of job.
What I try now is to re-design the current script with OO ideas and
the Xotcl package,
for which I am a complete newbie.
I defined a Task class, which contains the name of the task, the type
(Tcl command or
executable), the arguments of the task, the directory name, the log
file.
I also defined a Workflow class, which contains the name of the
workflow and
the list of tasks. The list of tasks is a simple Tcl list, that is to
say a list of strings.
I stuck on the following problem : how to define the composition in
Xotcl,
that is to say, how to say that the list of strings is a list of
instances of Tasks ?
This is the "has-a" relation, instead of the "is-a" relation
(derivation), which is
clearly implemented with the "-superclass" keyword in Xotcl.
Here is the script for the Task class. It contains a constructor, a
destructor and two simple methods :
- a configure method to set the attributes,
- a display method to ... to display.
task.tcl
package require XOTcl
#
# Defines the Task Class
#
xotcl::Class create Task
#
# Defines constructor
# Seehttp://wiki.tcl.tk/16293
# "In XOTcl never use non-positional arguments on instproc init."
#
Task instproc init {} {
#
# Set default values
#
xotcl::my set name ""
# type : "TclCommand", "BinaryExecutable"
xotcl::my set type ""
# Directory into which the Task is to be executed
xotcl::my set dirname ""
# Log file for that task
xotcl::my set logfile ""
# Command to execute
xotcl::my set command ""
# Command arguments
xotcl::my set cmdargs {}
return ""}
#
# Adds a configure method
#
Task instproc configure args {
foreach { key value } $args {
switch -- $key {
"-name" {
xotcl::my set name $value
}
"-type" {
switch -- $value {
"TclCommand" -
"BinaryExecutable" {
xotcl::my set type $value
}
default {
error "Unknown type $value"
}
}
}
"-dirname" {
xotcl::my set dirname $value
}
"-logfile" {
xotcl::my set logfile $value
}
"-command" {
xotcl::my set command $value
}
"-cmdargs" {
xotcl::my set cmdargs $value
}
default {
error "Unknown key \"$key\""
}
}
}
return ""}
#
# Returns a string report for the current task
#
Task instproc report { } {
set report ""
append report "=================\n"
append report "Task\n"
set name [xotcl::my set name]
append report "Name : $name\n"
set type [xotcl::my set type]
append report "Type : $type\n"
set command [xotcl::my set command]
append report "Command : $command\n"
set cmdargs [xotcl::my set cmdargs]
append report "Arguments : $cmdargs\n"
switch -- $type {
"TclCommand" {
}
"BinaryExecutable" {
set dirname [xotcl::my set dirname]
append report "Dirname : $dirname\n"
set logfile [xotcl::my set logfile]
append report "Logfile : $logfile\n"
}
default {
error "Unknown type \"$type\""
}
}
return $report}
#
# Displays a report onto the standard output.
#
Task instproc print { } {
set report [xotcl::my report]
puts $report
return ""
}
Here is the script for the Workflow class. It contains two methods :
- a method addTask to add a new task at the end of the workflow,
- a display method.
The addTask method is based on the "lappend" Tcl command.
The only place where the fact that the tasks are indeed instances of
the Task class is in the "report" method of the workflow, which
partly
delegates to the "report" method of the Task class.
workflow.tcl
package require XOTcl
source task.tcl
#
# Defines the Workflow Class
#
xotcl::Class create Workflow
#
# Defines constructor
#
Workflow instproc init { } {
xotcl::my set tasks {}
xotcl::my set name {}
return ""}
#
# A configure method
#
Workflow instproc configure { args } {
foreach { key value } $args {
switch -- $key {
"-name" {
xotcl::my set name $value
}
"-tasks" {
xotcl::my set tasks $value
}
default {
error "Unknown key \"$key\""
}
}
}
return ""}
#
# Adds a task
#
Workflow instproc addTask { task } {
xotcl::my lappend tasks $task}
#
# Returns a report for the workflow.
#
Workflow instproc report { args } {
set report ""
append report "=================\n"
append report "Workflow\n"
set name [xotcl::my set name]
append report "Name : $name\n"
set tasks [xotcl::my set tasks]
set tasknb [llength $tasks]
append report "Number of tasks : $tasknb\n"
for {set i 0} {$i<$tasknb} {incr i} {
set taskname [lindex $tasks $i]
append report "Task #$i/$tasknb: $taskname\n"
}
foreach taskname $tasks {
append report [$taskname report]
}
return $report}
#
# Print method
#
Workflow instproc print { } {
set report [xotcl::my report]
puts $report
return ""
}
The following is a simple driver. It creates 3 tasks.
Then it creates one workflow and the tasks one by one.
driver.tcl
package require XOTcl
source task.tcl
source workflow.tcl
#
# Creates a Task
#
Task initialization
initialization configure -name "Initialization" \
-type "TclCommand" \
-command "initialize"
Task startup
startup configure \
-name "Startup" \
-type "TclCommand" \
-command "startup"
Task myexe1
myexe1 configure \
-name "Compute Thing" \
-type "BinaryExecutable" \
-command "compute.exe" \
-cmdargs {number1} \
-logfile "report-compute.log" \
-dirname "computedir"
initialization print
set tasks [list initialization startup myexe1]
foreach taskname $tasks {
$taskname print
}
#
# Creates a Workflow
#
Workflow automation
automation configure -name "My First Workflow"
automation addTask initialization
automation addTask startup
automation addTask myexe1
automation print
# And now, add anything to make it crash
automation addTask myexeWhichDoesNotExist
automation print
When we add the task "myexeWhichDoesNotExist", there is no problem,
since it is a simple string.
But the "print" method makes xotcl shout :
invalid command name "myexeWhichDoesNotExist"
while executing
"$taskname report"
etc...
How to make xotcl shout at the call to addTask ?
Thanks for your help.
Best regards,
Michaël
Try the following:
in the addTask method, check
if {[mytaskvar info class] ne "Task"} {
treat the error...
}
it's ok here...
Stéphane A.
.
- References:
- Xotcl and composition
- From: relaxmike
- Xotcl and composition
- Prev by Date: Re: Why doesn't foreach return a value
- Next by Date: Re: Why doesn't foreach return a value
- Previous by thread: Xotcl and composition
- Next by thread: How can I use tcl to read files written in GBK or GB18030 encoding?
- Index(es):
Relevant Pages
|