Richard Suchenwirth 2005-12-12 - In the Tcl chatroom, CMcC said:
You know, in retrospect, I think [set x a b c] should be equivalent to [set x [list a b c]]
Well, Tcl is where wishes come true :) Here's my experimental code that overloads set, and seems to work fine, as far as I've tested. I had to reuse the _var name for upvar, so the error message comes right if the variable doesn't exist yet:
rename set _set proc set {_var args} { upvar 1 $_var $_var _set ll [llength [info level 0]] if {$ll==3} { _set $_var [lindex $args 0] } elseif {$ll>3} {_set $_var $args} _set $_var }
Lars H: Ehh... Why this insanely complicated solution? The user-supplied name for a local variable is just asking for trouble -- consider what happens for [set ll]!! The straightforward solution is rather:
proc set {varname args} { upvar 1 $varname var if {[llength $args] == 0} then { return $var } elseif {[llength $args] == 1} then { _set var [lindex $args 0] } else { _set var $args } }
RS: It is to avoid the misleading error message below - but I agree that variable ll opens a vulnerability, so your code is safer.
% set foo can't read "var": no such variable
Ingemar H: The above small problem is easily solved by this:
if {[llength $args] == 0} then { if {[info exists var]} { return $var } else { _set $varname }
The distinction between $ll==3 and $ll>3 is necessary so this frequent case comes right:
set something {}
Testing:
% source myset.tcl % set foo can't read "foo": no such variable % set foo 1 1 % set foo 1 % set bar 2 3 4 2 3 4 % set bar 2 3 4 % set grill {{}} {} % set grill {} % set nix {} % set nix %
So far it looks as expected. But bytecode compilation may lose performance if a fundamental like set is pulled from under its feet...