Ticket UUID: | 8e91ec4866db095f1d90d4e2fd468305a8a80bf8 | |||
Title: | {TCL LOOKUP VARNAME} vs {TCL READ VARNAME} | |||
Type: | Bug | Version: | 8.6 | |
Submitter: | aspect | Created on: | 2015-07-23 05:29:56 | |
Subsystem: | 07. Variables | Assigned To: | dkf | |
Priority: | 5 Medium | Severity: | Minor | |
Status: | Closed | Last Modified: | 2015-08-02 16:48:44 | |
Resolution: | Rejected | Closed By: | dkf | |
Closed on: | 2015-08-02 16:48:44 | |||
Description: |
I don't know what category to put this in - was hoping for something like "Exceptions". {TCL READ VARNAME} seems like a mistake - {TCL LOOKUP VARNAME} occurs more frequently in the source, and it is not clear to the script writer why one might trap one but not the other: % unset a % try {puts $a} on error {e o} {puts [dict get $o -errorcode]} TCL LOOKUP VARNAME a % apply {{} {try {puts $a} on error {e o} {puts [dict get $o -errorcode]}}} TCL READ VARNAME % try {apply {{} {puts $a}}} on error {e o} {puts [dict get $o -errorcode]} TCL READ VARNAME % try {puts $a(a)} on error {e o} {puts [dict get $o -errorcode]} TCL LOOKUP VARNAME a % array set a {} % try {puts $a(a)} on error {e o} {puts [dict get $o -errorcode]} TCL READ VARNAME Despite frequency of occurrence, READ seems to only be emitted from one location in the source: http://core.tcl.tk/tcl/artifact/0a01b4037e1d4eec?ln=1414 Where it has been since: http://core.tcl.tk/tcl/info/a12728cbb91807a8 While the test suite is mostly quite thorough with errors, it only touches {TCL * VARNAME} by accident, in cmdAH-23.6. The above examples seem like a good start for test cases, but I'm not sure what others should exist. | |||
User Comments: |
dkf added on 2015-08-02 16:48:44:
(text/html)
<blockquote><i>That distinction sounds very subtle to me.</i></blockquote> Yes, but that's how it is internally. When you put code into a procedure (well, anything with a Local Variable Table defined) you change how variables are located; simple variable references become a lot more efficient, and the lookup of them no longer fails ever, so no <tt>TCL LOOKUP VARNAME</tt> failure, yet the read might still fail if the variable entry refers to a currently unset variable, hence <tt>TCL VARNAME READ</tt> being the error code. <p> In short, Tcl does not guarantee to give exactly the same reason for failing in all cases where it generates a failure, even if those cases are superficially similar; those cases may be actually looking very different from Tcl's own internal perspective. I don't propose to alter anything, or document that this variation occurs. We might change it all without warning (but probably won't; we're lazy too!) aspect added on 2015-07-24 02:51:38: That distinction sounds very subtle to me. Var structures aren't something I'm familiar with from the script level, and I'm not sure I should be! It has struck me a few times, and anecdotally I have record of evilotto questioning the array behaviour on chat months ago. For the array cases I can sort of understand (LOOKUP if the array doesn't exist; READ if the element doesn't), but the difference between the first two cases isn't obvious. Is this interpreted vs bytecode paths? I don't see that the distinction aids the programmer to write correct code. Both produce exactly the same error message, giving no hint that the difference exists, and when I want to trap one I practically always want to trap both, which requires two independent trap clauses and code duplication. I think they should at least share a common prefix to facilitate this common case. Perhaps {TCL VARNAME READ} would have been a better structure, but I think that horse has bolted. Perhaps we can salvage something in the form of {TCL LOOKUP VARNAME $varName $op} but that's starting to look pretty cumbersome. {TCL LOOKUP VARNAME ?varName?} across the board seems pretty appealing to me right now. I could be convinced that it's useful to have distinct READ and LOOKUP error codes, but that moves the focus on to documentation. And this sounds like a right pain to explain to impatient novice programmers -- enough that I'd rather mess with code than prose ;-). dgp added on 2015-07-23 22:10:33: The LOOKUP code indicates something went wrong trying to map the variable name to a Var struct. The READ code indicates a Var struct was found without any trouble, but then it didn't hold any value. aku added on 2015-07-23 17:53:32: dgp - I actually don't. Is this documented somewhere ? (Manpage ?) dgp added on 2015-07-23 14:13:48: It does seem strange that the TCL READ VARNAME code fails to report the name of the variable that lacks a value. dgp added on 2015-07-23 14:09:54: You understand the distinction being made by the two -errorcode values, right? |