foo do-somethingshould be resolved, in case of no command foo being defined, like
namespace eval foo do-somethingA generalized approach, using whitespace as namespace separators, was proposed in http://people.manchester.ac.uk/~zzcgudf/tcl/future.html
Reinhard Max commented: A few weeks ago, I implemented parts of that concept in pure Tcl. Maybe it's a good starting point for a more sophisticated implementation: #
# by Reinhard Max <max@suse.de>
#
if {[info commands _unknown] eq ""} {
rename unknown _unknown
proc unknown {args} {
# get the namespace of the caller
# and set it to "" if it was the global namespace
set ns [uplevel 1 namespace current]
if {[string equal $ns ::]} {set ns ""} else {append ns ::}
append ns [lindex $args 0]
if {[catch {namespace children $ns}]} {
# The namespace doesn't exist,
# call the default [unknown] proc.
set ret [catch {uplevel 1 _unknown $args} val]
return -code $ret $val
}
# The namespace exists. Create a proc with the same name
# for executing subcommands in this namespace ...
eval [subst -nocommands {
proc $ns {command args} {
set code [catch {
uplevel 1 ${ns}::[set command] [set args]
} value]
return -code [set code] [set value]
}
}]
# ... and call it.
set ret [catch {uplevel 1 $ns [lrange $args 1 end]} val]
return -code $ret $val
}
package provide nslist 0.42
}Usage examples and test: tclsh8.3 > package require nslist
0.42
tclsh8.3 > namespace eval a { namespace eval b { proc c {} {puts c}}}
tclsh8.3 > a b c
c
tclsh8.3 > a
no value given for parameter "command" to "a"
while evaluating a
tclsh8.3 > a b
no value given for parameter "command" to "a::b"
while evaluating {a b}RS: It would be even more symmetric if we could write
proc {a b c} {} {puts c}instead of namespace eval a { namespace eval b { proc c {} {puts c}}}or proc a::b::c {} {puts c}e.g. by overloading the proc command to substitute spaces in the proc name with ::RM: Something like that?
#
# Wrapper around [proc] that allows commands inside namespaces
# to be provided as {a b c} instead of a::b::c .
#
proc nproc {args} {
set name [lindex $args 0]
set ns [join [lrange $name 0 end-1] ::]
set name [lindex $name end]
set args [lreplace $args 0 0 _proc_ $name]
set code [catch {namespace eval $ns $args} val]
regsub _proc_ $val proc val
return -code $code $val
}
rename proc _proc_
rename nproc procRS: I think [llength name] should be checked first: if ==1, calling the renamed _proc_ (ex proc) is sufficient.
RM: OK, here is a new version, that takes care about that. In addition, it chages the syntax to be:
proc a b c {arg1 arg2} {body}I think this fits better to the subcommand style. proc nproc {args} {
if {[llength $args] <= 3} {
set code [catch [linsert $args 0 _proc_] val]
regsub _proc_ $val proc val
return -code $code $val
}
set ns [join [lrange $args 0 end-3] ::]
set args [lreplace $args 0 end-3 _proc_]
set code [catch {namespace eval $ns $args} val]
regsub _proc_ $val proc val
return -code $code $val
}
