Introspection shortcomings

This page is about the cases where Tcl's powerful introspection facilities come up short — where there's simply no way to get at a particular piece of information (at least not fram the script level). Hopefully, by collecting them here we may inspire improvements in the language that can provide us with the missing power!

Of course, things might get entered on this page by mistake; maybe there was a way to find the wanted piece of information, it just wasn't what the poster expected? Well, all the better, since it meant Tcl was better! Don't delete the item, but move it down the page to a section of "introspection successes".

Also, there are some things that are unavailable by design (e.g. the type of internal representation in a Tcl_Obj). These also deserve a separate section, since they are not really shortcomings as such.

Introspection shortcomings

vwaited variables

There doesn't seem to be any way of finding out which variables are currently being vwaited upon.

ferrieux Notice that for a given interp at any given time there's at most one vwait which may be unlocked (the innermost one in case of nested vwaits). So this request should be "which variable" with no plural. Which may somewhat reduce its appeal :(

jbr: This is no longer true with coroutine, now you can vwait on several variables and have thier actions fire in any order. Yes?

Lars H: Mostly no. It is possible that the NRE reform can change vwait to be non-recursive (at the C level), in which case one could possibly wait on several variables simultaneously without deadlock, but I don't think that has happened yet. What coroutine adds is more the ability to emulate vwait by yielding to the main event loop (and doing better than the real thing by not deadlocking).

 -- Ah, I hadn't actually read the example and thought that it actually called vwait, but I see its a trace.  Thanks.

Introspection successes

chan mode

is about extending chan command to query whether a channel is readable and/or writable. Unfortunately it is not part of the Tcl core, but see the referenced pages yourself. (MAKR 2008-07-03)

Lars H: True, but what makes this an introspection success is that the core already provides a way of finding this out:

  catch {read $ch 0}

returns 0 if the channel was readable and 1 otherwise, not changing $ch in either case. Similarly

  catch {puts -nonewline $ch ""}

returns 0 if the channel was writable and 1 otherwise, not changing $ch in either case. Or is there a situation (something with stacked channels, perhaps?) where these actually have a side-effect?

global and variable-aliased vars

There seems to be no way to determine if $foo is a local or an alias for a global or namespace variable created through global or variable.

Lars H: This is what info locals is for! Consider:

 % proc test {} {
    set l 1
    upvar 1 u u; set u 2
    global g; set g 3
    variable n; set n 4
    list [info vars] [info locals]
 % test
 {l u g n} l

Introspection on aliases

interp always refers to aliases by the name they were created under, so since aliases can be renamed, there's ultimately no way of knowing what an alias command maps to, even if it goes from {} to {}! Consider:

% interp alias {} a {} puts a
% interp alias {} b {} puts b
% a
% b
% rename a c
% interp aliases {}
a b
% rename b a
% rename c b
% b
% a
% interp alias {} a
puts a
% interp alias {} b
puts b

See also:

However, even though interp is of no help, one can use trace to figure out what an alias maps to — provided one is prepared to risk calling it:

 proc which_alias {cmd} {
    uplevel 1 [list ::trace add execution $cmd enterstep ::error]
    catch {uplevel 1 $cmd} res
    uplevel 1 [list ::trace remove execution $cmd enterstep ::error]
    return $res

In the above case one gets:

 % which_alias a
 puts b
 % which_alias b
 puts a

namespace upvared variables

PYK 2014-08-12: When copying namespaces, it would be useful to treat namespace upvared variables differently than regular namespace variables, but there is no way to introspect that characteristic of a variable.

PYK 2014-08-18: An example from from aspect led to the following method, which is also now documented on the upvar page:

expr {![catch {upvar 0 varname varname}]}