#600 Retrieve last result in interactive mode

Don Porter

As suggested on comp.lang.tcl:


it could be nice to be able to retrieve the last interactive command's result or error, for debugging purposes in situations where things are not easily reproducible.

A simple API would be a [::tcl::lastresult] command.


  • Adds the ::tcl::lastresult command

  • The attached patch does just that.

    Implementation: it saves the interp's result object in the assoc area.
    Note that it is done at object level, not string, so that large values are efficiently handled. It does prorogate the life of the result object until the end of the next interactive command, but that's the price to pay while time machines are not affordable.

    • labels: --> 50. Embedding Support
    • assigned_to: nobody --> dgp
  • The Standard ML language uses the global 'it' variable for the same purpose. Note also that these should be considered to be features of tclsh/wish and not the Tcl language.

  • If you're suggesting an alternative API please voice it clearly.
    The patch is confined to tclMain.c and tclHistory.c which are parts of tclsh, and done so that non-interactive execution isn't penalized. Any form of criticism welcome here; I'm not too eager to TIP that now, given the current pipeline of unvoted TIP / uncommitted patches that I have :/

  • I agree to dkf, that a short-named global variable would be nicer. (my preference would be for "$_")

    A command (especially in ::tcl namespace) may misguide people into believing that it was a tcl-feature rather than one of tclsh. (I'm not aware of any tclsh-specific commands so far, but argv and argv0 are already precedents for tclsh's own preinitialized variables.)

    No magic is necessary for that variable apart from that it is overwritten after each eval'ed command. e.g. puts "[set _ 42] $_" would print twice 42, and afterwards $_ would be empty for puts' result.

    Thanks for taking the effort in the first place! It's appreciated!

  • Acknowledging the remark about language vs. interpreter, I refactored the patch so that it now uses a call-back (rather than call-forward) API in history.tcl.
    So the external API for retrieval is now [history lastresult], and the only affected files are: tclHistory.c and history.{tcl,test,n}.(Yes it is complete with test and doc).

    As for the final, easy-to-type shortcut, I'm a bit uneasy about hijacking a toplevel variable like $::_ or $::it for obvious compatibility reasons (though again it only touches interactive sessions). A TIP is needed for _that_, while I guess it is not for the current patch.

    Please review.

  • A small tidbid: a typo in the second manpage-addings: "... [history lastesult]." ("r" missing)

    And a suggestion for $_: in interactive mode, make a read-trace on variable "_" to overwrite the variable with [history lastresult].

    Eventually make a write-trace too, that just turns off both of these traces, (unless called from the read-trace), so if anything else sets "_" it won't get overwritten anymore.

  • PS: I definitely prefer the second patch to the first one - big "thank you" again.

  • I meant the second one that you added. "histresult.patch" - It makes it clear, that this is not for scripts (except of course if they do their own command-loop with history).

  • Refactored along history.tcl style + Andreas' fix

  • Typo fixed, thanks.
    For the traces I don't know. It feels complicated and generates extra references (you'll see them with [rep] ;-). A simpler method is to rewrite the script-level callback [hist result]: proc ::tcl::HistResult x {set ::_ $x}. Of course this breaks [hist result] but doesn't introduce lingering references...

  • Thanks to the brilliant design, it's as simple as: upvar #0 ::tcl::history(lastcommand) _

    My suggestion of traces was to not get in user's way were he to use "_" himself.

  • Jeffrey Hobbs
    Jeffrey Hobbs

    FWIW, tkcon also uses $::_ for the last result.

  • Now, how's it going on? What's this patch's possible route into the core? TIP?