1
votes

In my TCL script I'm using several procedures that I don't have the source for. All these procedures do some tasks and output a lot of messages. But I just want the tasks to be done and I want to suppress the messages. Is there a way to do this.

So for example I would like to run a procedure like so:

my_proc $arg1 $arg2 $arg3

and suppress all it's messages. Any workarounds/ smart alternatives are appreciated.

More info: I'm using a custom shell that takes a TCL file as an argument and runs it. Inside this custom shell I have access to some TCL procedures for which I don't have the code.

Or even is there any way I can have the output of the script go to a file instead of the command prompt (stdout)?

1
Can you just do: set output [my_proc $args]?glenn jackman
@Glenn I tried, it still prints stuff. I think there are a bunch of puts statements in the proc code that I don't have access to.Arash Fotouhi
I was thinking about the shell I think. My comment was dumb.glenn jackman

1 Answers

5
votes

Try altering puts in your code:

rename ::puts ::tcl_puts
proc puts args {}        ;# do nothing

Then, if you want to print something, use tcl_puts

This is a bit of a nuclear option. You can get subtler:

proc puts args {
    if {[llength $args] == 1} {
        set msg [lindex $args 0]
        # here you can filter based on the content, or just ignore it
        # ...
    } else {
        # in the 2a\-args case, it's file io, let that go
        # otherwise, it's an error "too many args"
        # let Tcl handle it
        tcl_puts {*}$args

        # should probably to stuff there so that errors look like
        # they're coming from "puts", not "tcl_puts"
    }
}

Another thought: just do it for the duration of the command you're calling:

proc noputs {args} {
    rename ::puts ::tcl_puts
    proc ::puts args {}

    uplevel 1 $args

    rename ::puts ""
    rename ::tcl_puts ::puts
}

noputs my_proc $arg1 $arg2 $arg3

Demo:

$ tclsh
% proc noputs {args} {
    rename ::puts ::tcl_puts
    proc ::puts args {}

    uplevel 1 $args

    rename ::puts ""
    rename ::tcl_puts ::puts
}
% proc my_proc {foo bar baz} {
    lappend ::my_proc_invocations [list $foo $bar $baz]
    puts "in myproc with: $foo $bar $baz"
}
% my_proc 1 2 3
in myproc with: 1 2 3
% noputs my_proc a b c
% my_proc x y z
in myproc with: x y z
% set my_proc_invocations
{1 2 3} {a b c} {x y z}