jimtcl
jimtcl copied to clipboard
Strange results (duplicates) from [info commands]
$ cat ictest.tcl
proc q {} { puts &[info commands *::acmd]& }
namespace eval a {
proc z {} { puts ^[info commands *::acmd]^ }
namespace eval b {
proc x {} { puts @[info commands *::acmd]@ }
namespace eval c {
proc acmd {} {}
puts ![info commands *::acmd]!
::a::z
::a::b::x
::q
}
}
}
puts %[info commands *::acmd]%
$ jimsh ictest.tcl
!a::b::c::acmd!
^b::c::acmd a::b::c::acmd^
@c::acmd a::b::c::acmd@
&a::b::c::acmd&
%a::b::c::acmd%
Thanks for the report. The issue is that there are two names that acmd can be known by in these namespaces. Either name will work, but they are the same proc. I'll have a think about if/how to resolve this.
My inclination is to leave it as is, but I'm open to other suggestions
I don't think "commands reachable" should be considered the same as "commands available".
$ cat ictest2.tcl
namespace eval a {
namespace eval b {
proc getcmds {pat} {
return [info commands $pat]
}
proc q {} { return 1 }
namespace eval c {
proc q {} { return 2 }
}
}
}
foreach cmd [a::b::getcmds *::q] {
puts $cmd![$cmd]!
}
$ jimsh ictest2.tcl
ictest2.tcl:13: Error: invalid command name "c::q"
at file "ictest2.tcl", line 13
$ cat ictest3.tcl
namespace eval a {
proc getcmds {pat} { info commands $pat }
namespace eval b {
proc getcmds {pat} { info commands $pat }
namespace eval c {
proc getcmds {pat} { info commands $pat }
}
}
}
# ok
set pat ::*::getcmds
# notok
set pat *::getcmds
puts [a::getcmds $pat]
puts [a::b::getcmds $pat]
puts [a::b::c::getcmds $pat]
puts [info commands $pat]
$ jimsh ictest3.tcl
b::c::getcmds b::getcmds a::getcmds a::b::c::getcmds a::b::getcmds
c::getcmds a::getcmds a::b::c::getcmds a::b::getcmds
a::getcmds a::b::c::getcmds a::b::getcmds
a::getcmds a::b::c::getcmds a::b::getcmds
I'm not sure I follow you. [info commands] returns commands that are reachable from the scope where it is invoked. Why would those be callable from another scope (such as the global scope in your first example)?
Consider:
namespace eval a {
proc getcmds {pat} { info commands $pat }
proc testing {pat} {
foreach name [info commands $pat] {
puts "from a::testing: $name => [$name getcmds]"
}
}
namespace eval b {
proc getcmds {pat} { info commands $pat }
namespace eval c {
proc getcmds {pat} { info commands $pat }
}
}
}
a::testing *::getcmds
Gives:
from a::testing: b::c::getcmds => getcmds
from a::testing: b::getcmds => getcmds
from a::testing: a::getcmds => getcmds
from a::testing: a::b::c::getcmds => getcmds
from a::testing: a::b::getcmds => getcmds
So each of those commands is callable from the 'a' namespace, although some are ultimately aliases of others. But it doesn't mean you could call 'b::getcmds' from the global namespace.
Perhaps also consider:
proc aa {} {}
alias aa2 aa
puts [info commands aa*]
Gives:
aa2 aa
We wouldn't expect 'info commands' to de-duplicate these even though aa2 is simply an alias of aa.
I'm going to close this issue as "possibly unexpected but not wrong"