Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.* 1 > Newsgroup comp.lang.tcl

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 07-12-2012, 07:02 PM
bmburstein@gmail.com
Guest
 
Posts: n/a
Default Question understanding variable expansion

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.
Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 07-12-2012, 07:23 PM
Eugene
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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.
Reply With Quote
  #3 (permalink)  
Old 07-12-2012, 07:33 PM
Prof Craver
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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
Reply With Quote
  #4 (permalink)  
Old 07-12-2012, 07:35 PM
bmburstein@gmail.com
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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.


Reply With Quote
  #5 (permalink)  
Old 07-12-2012, 08:14 PM
Uwe Klein
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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
Reply With Quote
  #6 (permalink)  
Old 07-12-2012, 08:40 PM
Alexandre Ferrieux
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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
Reply With Quote
  #7 (permalink)  
Old 07-12-2012, 10:59 PM
Robert Heller
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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



Reply With Quote
  #8 (permalink)  
Old 07-13-2012, 05:12 AM
Joe English
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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
Reply With Quote
  #9 (permalink)  
Old 07-13-2012, 09:06 AM
M. Strobel
Guest
 
Posts: n/a
Default Re: Question understanding variable expansion

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!"
Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 05:25 AM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.