GN This is a simple study for a chan command as suggested in TIP 208 by using
XOTcl. The following commands are implemented
chan blocked ; # fblocked
chan close ; # close
chan fconfigure ; # fconfigure
chan open ; # open
chan puts ; # puts
We define here a Class chan, which is used to provide an ensemble-like interface as well as an object oriented interface (creating instances). We use here xotcl's forwarding mechanism. The same could be achieved via renaming or by implementing the methods in C.
Class chan
chan proc unknown {m args} {
chan puts "unknown chan method '$m $args' called
defined: [lsort [my info commands]]"
}
chan forward blocked ::fblocked
chan forward close ::close
chan forward fconfigure ::fconfigure
chan forward open ::open
chan forward puts ::puts
Now we can use the chan command:
set c [chan open /tmp/junk w]
chan puts -nonewline $c "hello"
chan puts $c " world"
chan close $c
chan xxx
In order to define an OO interface for streams, we can extend the definitions:
# allow configuration of a stream name
chan parameter stream
# redefine "new" such it creates and
# opens a stream and creates as well an instance
chan proc new args {
set stream [eval chan open $args]
my create $stream -stream $stream ;# create object
}
# close stream and destroy object
chan instproc destroy {} {
chan close [my stream]
next
}
# handle other subcommands (methods) via unknown
chan instproc unknown {m args} {
set valid [lsort [chan info instcommands]]
stderr puts "unknown chan method '$m' $args called;
defined methods: $valid"
}
# define forwarders to the chan ensemble
chan instforward puts ::chan puts {%@-1 %my stream}
chan instforward blocked ::chan fblocked {%my stream}
chan instforward fconfigure ::chan fconfigure {%my stream}
# create standard streams
chan create stdout -stream stdout
chan create stderr -stream stderr
Now we can use the chan OO interface:
set c [chan new /tmp/junk w]
$c puts -nonewline "hello"
$c puts -nonewline " world"
$c puts ""
$c xxx
stderr puts "currently open streams: [chan info instances]"
$c destroy
stderr puts "currently open streams: [chan info instances]"
A reflection interface an be established
- on the object level (per stream) via a mixin class, or
- on the class level (for all streams) via a instmixin class,
- as well as a mixin on the chan command...
Class StreamReflect
foreach m {puts blocked fconfigure} {
StreamReflect instproc $m args {
puts stderr " before [self proc] $args"
set r [next]
puts stderr " after [self proc] returning <$r>"
return $r
}
}
puts =====
chan instmixin StreamReflect
set c [chan new /tmp/junk w]
$c puts "hello"
stderr puts "currently open streams: [chan info instances]"
$c destroy
puts =====
chan mixin StreamReflect
set c [chan open /tmp/junk w]
chan puts $c "hello"
chan close $c
puts =====