Tcl Source Code

View Ticket
Login
Ticket UUID: 2927535
Title: Retrieve last result in interactive mode
Type: Patch Version: None
Submitter: ferrieux Created on: 2010-01-07 13:55:13
Subsystem: 50. Embedding Support Assigned To: dgp
Priority: 5 Medium Severity:
Status: Open Last Modified: 2010-02-21 06:34:44
Resolution: None Closed By:
    Closed on:
Description:
As suggested on comp.lang.tcl: 

http://groups.google.com/group/comp.lang.tcl/browse_frm/thread/c78f6d63471cccb7/5ddedc4e11bfa754#5ddedc4e11bfa754

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.
User Comments: avl42 added on 2010-02-21 06:34:44:
Now, how's it going on?  What's this patch's possible route into the core?  TIP?

hobbs added on 2010-01-19 05:21:24:
FWIW, tkcon also uses $::_ for the last result.

avl42 added on 2010-01-19 04:53:54:
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.

ferrieux added on 2010-01-19 02:59:50:
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...

ferrieux added on 2010-01-19 02:54:51:

File Deleted - 358197:

ferrieux added on 2010-01-19 02:54:36:

File Added - 359387: histresult.patch

avl42 added on 2010-01-19 02:40:44:
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).

avl42 added on 2010-01-19 02:22:25:
PS: I definitely prefer the second patch to the first one - big "thank you" again.

avl42 added on 2010-01-19 02:20:32:
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.

ferrieux added on 2010-01-08 21:07:32:

File Added - 358197: histresult.patch

ferrieux added on 2010-01-08 21:06:39:
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.

avl42 added on 2010-01-08 18:20:52:
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!

ferrieux added on 2010-01-07 21:50:17:
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 :/

dkf added on 2010-01-07 21:35:10:
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.

ferrieux added on 2010-01-07 20:58:47:
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.

ferrieux added on 2010-01-07 20:56:37:

File Added - 358030: lastresult.patch

Attachments: