Search code examples
tcltclsh

How to hide a command (not disable) in tclsh


In tclsh I would like to hide a command that cannot be called directly but can be called in a certain way. Is there a good way to do this or an idea that I can look into.


Solution

  • You can hide commands, provided they are in the global namespace (I know that's ugly!) using the interp hide command. You then use interp invokehidden to call them, and interp expose to undo the hiding:

    % proc hideme args {puts "HIDDEN: args=$args"}
    % hideme foo
    HIDDEN: args=foo
    % interp hide {} hideme
    % hideme foo
    invalid command name "hideme"
    % interp invokehidden {} hideme foo
    HIDDEN: args=foo
    % interp hidden {}
    hideme
    % interp expose {} hideme
    % interp invokehidden {} hideme foo
    invalid hidden command name "hideme"
    % hideme foo
    HIDDEN: args=foo
    

    This is part of the security mechanisms in Tcl, but only when the command is hidden by a parent interpreter. In the case above, it technically isn't because you're hiding from yourself and can find the hidden command again. There's no security without a security boundary. (The {} is the empty string and is the "name" of the current interpreter with respect to itself.)

    Safe interpreters hide many standard commands, leaving the interpreter unable to interact with the OS by default.