Home > Archive > Tcl > July 2004 > TIP #208: Add a 'chan' Command
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
TIP #208: Add a 'chan' Command
|
|
| Jeff Hobbs 2004-07-16, 3:59 pm |
|
TIP #208: ADD A 'CHAN' COMMAND
================================
Version: $Revision: 1.1 $
Author: Jeff Hobbs <jeffh_at_activestate.com>
State: Draft
Type: Project
Tcl-Version: 8.5
Vote: Pending
Created: Friday, 02 July 2004
URL: http://purl.org/tcl/tip/208.html
WebEdit: http://purl.org/tcl/tip/edit/208
Post-History:
-------------------------------------------------------------------------
ABSTRACT
==========
This TIP proposes adding a *chan* command that would serve as a
top-level command container for all the related channel commands that
have proliferated over time, as well as future new channel-based
commands.
RATIONALE
===========
Tcl's channel system has evolved over time from a thin layer on top of
the OS into a very complex, multi-platform system. There are numerous
top-level commands for channels already, with more being proposed for
Tcl 8.5. This command would centralize them, making it easier for new
users to see all the related channel commands, much as *string* or
*file* operate today.
The name *chan* was chosen over /channel/ because it is a clearly
recognizable abbreviation, much like /eval/ vs. /evaluate/ and /interp/
vs /interpreter/.
SPECIFICATION
===============
A new command *chan* will be added with the following syntax:
chan blocked ; # fblocked
chan close ; # close
chan configure ; # fconfigure
chan copy ; # fcopy
chan eof ; # eof
chan event ; # fileevent
chan flush ; # flush
chan gets ; # gets
chan puts ; # puts
chan read ; # read
chan s ; # s
chan tell ; # tell
Each represents the existing command that is commented. The arguments
to each would remain what the current command takes.
Note that *open* is not included above, as it is a channel creation
function, just like *socket*.
FUTURE POSSIBILITIES FOR EXTENDING THE 'CHAN' COMMAND
-------------------------------------------------------
I would also recommend that [TIP #206] be integrated as *chan
truncate*. Further TIPs may also recommend subcommands such as *chan
transform*, *chan stack* and *chan unstack* (exposing the channel
stacking subsystem available in the C API), among other possibilities.
DEPRECATION OF EXISTING COMMANDS
----------------------------------
In addition, I would recommend only the following commands be marked
deprecated so as to help systematize their names better:
fblocked
fconfigure
fcopy
fileevent
REFERENCE IMPLEMENTATION
==========================
The implementation of this TIP is really a simple command that makes
use of the existing command implementations. It could be a namespace
ensemble or a C-based command.
COPYRIGHT
===========
This document has been placed in the public domain.
-------------------------------------------------------------------------
TIP AutoGenerator - written by Donal K. Fellows
[[Send Tcl/Tk announcements to tcl-announce@mitchell.org
Announcements archived at http://groups.yahoo.com/group/tcl_announce/
Send administrivia to tcl-announce-request@mitchell.org
Tcl/Tk at http://tcl.tk/ ]]
| |
| Andrew Mangogna 2004-07-21, 3:57 am |
| Jeff Hobbs wrote:
>
> TIP #208: ADD A 'CHAN' COMMAND
> ================================
[snip]
I'm a little surprised that there hasn't been any discussion of this TIP.
But let me chime in with my concurrence with the TIP. The continuing
re-organization of related commands into ensembles is welcome.
Andrew
| |
| Alexander Danilov 2004-07-21, 3:57 am |
| I suggest to make channel act like object commands. It is more convinient, IMHO.
Look at my demo below:
#!/usr/bin/tclsh
# another variant of TIP #208: ADD A 'CHAN' COMMAND
# (c) 2004 Alexander Danilov <daapp@land.ru>
package provide tip208
rename unknown tcl::unknown
namespace eval tip208 {
set oldCommands {
fblocked close fconfigure fcopy
eof fileevent flush gets
puts read s tell
}
foreach cmd $tip208::oldCommands {
rename ::$cmd ::tcl::${cmd}
}
interp alias {} ::puts {} ::tcl::puts
interp alias {} ::gets {} ::tcl::gets
}
proc unknown {cmd args} {
set channel $cmd
set command [lindex $args 0]
set newArgs [lrange $args 1 end]
if {[lsearch [file channels] $channel] != -1 &&
[lsearch $::tip208::oldCommands $command] != -1} {
eval tcl::${command} $channel $newArgs
} else {
eval ::tcl::unknown $cmd $args
}
}
### end of package
if {[info ex argv0] && [file tail [info script]] == [file tail $argv0]} {
puts "Begin test."
puts "Available commands: [lsort [info commands]]"
puts "Your /etc/passswd:"
set passwd [open /etc/passwd r]
while {![$passwd eof]} {
stdout puts [$passwd gets]
}
stdout puts "Size of /etc/passwd: [$passwd tell]"
$passwd close
puts "Press Enter..."
gets stdin
}
| |
| Michael Schlenker 2004-07-21, 9:00 am |
| Alexander Danilov wrote:
> I suggest to make channel act like object commands. It is more convinient, IMHO.
Basically its just a question of style, there is no real user visible
difference between:
close $chan
$chan close
Its a cultural difference like the grammar structure in natural
languages, you can have subject predicate object (SPO) or predicate
subject object (PSO), or any other combination and all versions exist in
natural languages.
If we use a thing like:
chan close $chan
it is directly clear what happens, while it isn't if using an object style:
$xyz close
So you have to lookup what is stored in xyz, while the chan close would
just throw an error if it isn't whats expected.
You could argue that it is a good thing, as one can use common subsets
of subcommands, but at least I find myself always looking through
documentation of object interfaces to find out "what methods does this
object have", while i quite easily graps what objects i can pass to a
command i know of.
If Tcl adopts OO as a basic language principle i would say it would be
sensible to do everything OO, but as you demonstrated with your example
implementation you are free to do so right now, if it fits your mindset
without major problems.
Michael
| |
| Alexander Danilov 2004-07-22, 3:57 am |
| Michael Schlenker <schlenk@uni-oldenburg.de> wrote in message news:<2m7262FjrveeU1@uni-berlin.de>...
> Alexander Danilov wrote:
>
> Basically its just a question of style, there is no real user visible
> difference between:
>
> close $chan
> $chan close
>
I think that new C API (I mean Object commands) suggest to use
objects, so I assume that Tcl will use this way in near future. I am
not an opponent of procedural or functional style.
> Its a cultural difference like the grammar structure in natural
> languages, you can have subject predicate object (SPO) or predicate
> subject object (PSO), or any other combination and all versions exist in
> natural languages.
>
> If we use a thing like:
> chan close $chan
>
> it is directly clear what happens, while it isn't if using an object style:
>
> $xyz close
>
> So you have to lookup what is stored in xyz, while the chan close would
> just throw an error if it isn't whats expected.
>
> You could argue that it is a good thing, as one can use common subsets
> of subcommands, but at least I find myself always looking through
> documentation of object interfaces to find out "what methods does this
> object have", while i quite easily graps what objects i can pass to a
> command i know of.
I try to unify interface of different parts of Tcl: Tk use object
commands, Tcl use procedural style. It is not a big problem, but not
very convinient.
You use documentation, because Tcl has not enough introspection
capabilities. I mean this no way (IMHO, may be I forget?) to ask
command about subcommands or subcommand about options(required or
optional). Example from Ruby:
STDOUT.methods
return method of object STDOUT. If you would have such possibility you
would use documentation rare. I would like to have such feature in
Tcl. But it is a subject of another TIP.
>
> If Tcl adopts OO as a basic language principle i would say it would be
> sensible to do everything OO, but as you demonstrated with your example
> implementation you are free to do so right now, if it fits your mindset
> without major problems.
>
> Michael
| |
| Gustaf Neumann 2004-07-29, 8:57 am |
| well, "not enough introspection" ...
Here are two short studies for implementing the discussed
features in xotcl.
---
study 1: as specified in the TIP (can be easily extended to
the full set of subcommands):
Object chan
chan proc unknown {m args} {
chan puts "unknown chan method '$m $args' called \
defined: [lsort [my info commands]]"
}
rename fblocked ::chan::blocked
rename close ::chan::close
rename fconfigure ::chan::configure
rename open ::chan::open
rename puts ::chan::puts
set c [chan open /tmp/junk w]
chan puts $c "hello"
chan close $c
chan xxx
this will produce the following output:
unknown chan method 'xxx ' called
defined: blocked close configure open puts unknown
.... and of course the file in /tmp
Note, that one can define in a incremental step new
subcommands (in tcl or c) which can be
registered/redefined/deregistered dynamically
for the object "chan", the unknown will return the correct
set of methods.
---
study 2: define a class for channels, where every channel
is an instance; this is the "OO manner", where open creates
a stream and close destroys it.
Class chan -parameter stream -array set map {
blocked fblocked
configure fconfigure
puts puts
}
# create stream and object
chan proc open args {
set stream [eval open $args]
my create $stream -stream $stream ;# make an object
}
# close stream and destroy object
chan instproc close {} {
close [my stream]
[self] destroy
}
# handle other subcommands (methods) via unknown
chan instproc unknown {m args} {
[self class] instvar map
if {[info exists map($m)]} {
eval $map($m) [my stream] $args
} else {
set valid [lsort [concat \
[chan info instprocs] \
[array names map]]]
stderr puts "unknown chan method '$m' $args called;
defined: $valid"
}
}
chan create stdout -stream stdout
chan create stderr -stream stderr
set c [chan open /tmp/junk w]
$c puts "hello"
$c xxx
stderr puts "currently open streams: [chan info instances]"
$c close
stderr puts "currently open streams: [chan info instances]"
The output here is:
unknown chan method 'xxx' called;
defined: blocked close configure puts unknown
currently open streams: ::stderr ::stdout ::file5
currently open streams: ::stderr ::stdout
as you see, you get introspection about the current open
streams as well. xotcl allows you to define per object
methods (procs) such that certain special streams can
have special handlings. you get the whole set of methods
via e.g. [stderr info methods]. then you can have per-class
and per-object mixins, such you can do things like tee-streams
quite easy.
Concerning the implementation: Certainly the definition
of the methods can be done as well in C, such that the
overhead can be quite low. Future versions of xotcl
will have more powerful forwarding capabilities such that the
second verison can be made simpler as well...
This shows that defining a full-fledged tcl in oo style
is not so complicated and can co-exist with function
based style (e.g. for using "legacy" components)
-gustaf
|
|
|
|
|