Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
486 views
in Technique[技术] by (71.8m points)

tcl - apparent inconsistency read/write variable

I'm learning about Tcl just now. I've seen just a bit of it, I see for instance to create a variable (and initialize it) you can do

    set varname value

I am familiarizing with the fact that basically everything is a string, such as "value" above, but "varname" gets kind of a special treatment I guess because of the "set" built-in function, so varname is not interpreted as a string but rather as a name. I can later on access the value with $varname, and this is fine to me, it is used to specify varname is not to be considered as a string. I'm now reading about lists and a couple commands make me a bit confused

    set colors {"aqua" "maroon" "cyan"}
    puts "list length is [llength $colors]"
    lappend colors "purple"

So clearly "lappend" is another one of such functions like set that can interpret the first argument as a name and not a string, but then why didn't they make it llength the same (no need for $)?

I'm thinking that it's just a convention that, in general, when you "read" a variable you need the $ while you don't for "writing".

question from:https://stackoverflow.com/questions/65831542/apparent-inconsistency-read-write-variable

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Names are strings. Or rather a string is a name because it is used as a name. And $ in Tcl means “read this variable right now”, unlike in some other languages where it really means “here is a variable name”.

The $blah syntax for reading from a variable is convenient syntax that approximately stands in for doing [set blah] (with just one argument). For simple names, they become the same bytecode, but the $… form doesn't handle all the weird edge cases (usually with generated names) that the other one does. If a command (such as set, lappend, unset or incr) takes a variable name, it's because it is going to write to that variable and it will typically be documented to take a varName (variable name, of course) or something like that. Things that just read the value (e.g., llength or lindex) will take the value directly and not the name of a variable, and it is up to the caller to provide the value using whatever they want, perhaps $blah or [call something].

In particular, if you have:

proc ListRangeBy {from to {by 1}} {
    set result {}
    for {set x $from} {$x <= $to} {incr x $by} {
        lappend result $x
    }
    return $result
}

then you can do:

llength [ListRangeBy 3 77 8]

and

set listVar [ListRangeBy 3 77 8]
llength $listVar

and get exactly the same value out of the llength. The llength doesn't need to know anything special about what is going on.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...