|
|||
|
Why does something crazy like this work
set $x pu set $y ts $x$y hello outputs "hello", but neither of these work: set $x {puts hello} $x or set $x[list puts hello] $x I would think the variable substitution phase (as evident in the first example) would just replace the line `$x` with `puts hello`, and then run that line. |
|
|
||||
|
||||
|
|
|
|||
|
On 12.07.2012 23:02, bmburstein@gmail.com wrote:
> Why does something crazy like this work > > set $x pu > set $y ts > $x$y hello > > outputs "hello", but neither of these work: > > set $x {puts hello} > $x > > or > > set $x[list puts hello] > $x > > I would think the variable substitution phase (as evident in the first example) would just replace the line `$x` with `puts hello`, and then run that line. First of all - 'set $x pu' doesn't work, and no wonder - there's no x defined. There's no need to use $ when you assign a value to a variable. Second - if you want to put some command into a variable and then run it, expand it first: set cmd {puts hello!} {*}$cmd -- WBR, Eugene. |
|
|||
|
On Thursday, July 12, 2012 3:02:50 PM UTC-4, bmbur...@gmail.com wrote:
> I would think the variable substitution phase (as evident in the first example) would just replace the line `$x` with `puts hello`, and then run that line. Hi, This doesn't work because the interpreter treats $x as the procedure to run.. There is no procedure called "puts\ hello". When you write $x ....by itself, the interpreter expands $x into the first word in a command line invocation. If you put an entire command line in $x, the interpreter will look for a procedure with that entire command line as its name, which will produce unwanted results. You can instead [eval $x], which breaks $x into parts and runs the first word as the command with the remainder as arguments. As Eugene wrote above {*}$x does the same thing. Your intuition probably tells you that [$x] should be replaced with the line "puts hello", and if you type the line "puts hello" it will puts hello. However, the Tcl interpreter is not line-centric: it does not assemble a command line of characters out of your variables and then execute the line as if you typed it. Tcl is list-centric: it accepts your command as a space-delimited list, and makes all the substitutions for each list element. If your command is "puts $x $y", for example, Tcl is going to run a command with two arguments even if $y is 10 words. --S |
|
|||
|
On Thursday, July 12, 2012 10:23:18 PM UTC+3, Eugene wrote:
> On 12.07.2012 23:02, bmburstein@gmail.com wrote: > > Why does something crazy like this work > > > > set $x pu > > set $y ts > > $x$y hello > > > > outputs "hello", but neither of these work: > > > > set $x {puts hello} > > $x > > > > or > > > > set $x[list puts hello] > > $x > > > > I would think the variable substitution phase (as evident in the first example) would just replace the line `$x` with `puts hello`, and then run that line. > First of all - 'set $x pu' doesn't work, and no wonder - there's no x > defined. There's no need to use $ when you assign a value to a variable. My mistake when typing it into the browser. I did it right in the actual tcl program. > Second - if you want to put some command into a variable and then run > it, expand it first: > set cmd {puts hello!} > {*}$cmd Can you explain how exactly this works? What is {*}? > > -- > WBR, Eugene. |
|
|||
|
bmburstein@gmail.com wrote:
> Can you explain how exactly this works? What is {*}? > rather new syntax : expand a list to inline elements i.e. set list [ list c d e f g] mycommand a b {*}$list h i j expands to mycommand a b c d e f g h i j uwe |
|
|||
|
On Jul 12, 9:02*pm, bmburst...@gmail.com wrote:
> Why does something crazy like this work > > * * set $x pu > * * set $y ts > * * $x$y hello > > outputs "hello", but neither of these work: > > * * set $x {puts hello} > * * $x > > or > > * * set $x[list puts hello] > * * $x > > I would think the variable substitution phase (as evident in the first example) would just replace the line `$x` with `puts hello`, and then run that line. That would happen in Bourne Shell, not in Tcl. To summarize this key divergence: - Sh: substitute, then tokenize - Tcl: tokenize, then substitute -Alex |
|
|||
|
At Thu, 12 Jul 2012 12:02:50 -0700 (PDT) bmburstein@gmail.com wrote:
> > Why does something crazy like this work > > set $x pu > set $y ts > $x$y hello > > outputs "hello", but neither of these work: > > set $x {puts hello} > $x > > or > > set $x[list puts hello] > $x > > I would think the variable substitution phase (as evident in the > first example) would just replace the line `$x` with `puts hello`, and > then run that line. What you want is: set $x {puts hello} eval $x or set $x[list puts hello] eval $x The difference is the order of the operations and the state of command processing. When the variable substitution phase processes the command line set $x {puts hello} $x It yields a string (with two words). It is not a command line with two words, as is the case of set x "puts" set y "hello" $x $y -- Robert Heller -- 978-544-6933 / heller@deepsoft.com Deepwoods Software -- http://www.deepsoft.com/ () ascii ribbon campaign -- against html e-mail /\ www.asciiribbon.org -- against proprietary attachments |
|
|||
|
bmburstein asked:
> Why does something crazy like this work > > set $x pu > set $y ts > $x$y hello > > outputs "hello", but neither of these work: > > set $x {puts hello} > $x > > or > > set $x[list puts hello] > $x All is explained in the 12 rules of Tcl syntax: <URL: http://tmml.sourceforge.net/doc/tcl/Tcl.html > But basically: Tcl first parses the statement into words; next performs substitution on each word; and finally interprets the first argument as a command and invokes it with the remaining arguments. In the first example: set x pu; set y ts; $x$y hello parsing gives two words, "$x$y" and "hello"; substitution results in two arguments, "puts" and "hello"; the first word is a valid command name. In the second example: set $x {puts hello} ; $x parsing gives one word, {puts hello}, which is not a valid command name. Note that it's legal -- though perhaps not good style -- to say things like: proc {puts hello} {} { puts "Command with funny name called" } set $x {puts hello} $x > I would think the variable substitution phase > (as evident in the first example) would just > replace the line `$x` with `puts hello`, and > then run that line. That's how Unix shells usually work, but not Tcl. (Tcl's approach actually makes things quite a bit easier -- "quoting hell" is much worse in shell scripts, in Tcl it's practically nonexistant once you understand the rules.) --Joe English |
|
|||
|
Am 12.07.2012 21:35, schrieb bmburstein@gmail.com:
>> Second - if you want to put some command into a variable and then run >> it, expand it first: >> set cmd {puts hello!} >> {*}$cmd > Can you explain how exactly this works? What is {*}? to make the whole list philosophy explanation short: strobel@s114-intel:~> tclsh % set l[list one two three] one two three % proc show args {puts "Count of arguments: [llength $args]"} % show $l Count of arguments: 1 % show {*}$l Count of arguments: 3 % In your example: without the {*} the interpreter would search for the command "puts hello!" |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|