• Why do we need "eval"? (Expect question)

    From Kenny McCormack@21:1/5 to All on Thu Sep 12 15:07:41 2024
    Consider this (Unix/Linux/bash) command line:

    $ expect -- /dev/fd/3 3<<< 'eval spawn -noecho printf {{\t%s\n}} $argv;interact' $(seq 1 10)

    This correctly generates the output (each line starts with a tab):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    But notice how we have to use "eval" in order to split up the args in $argv. And, since we are using "eval", we have to "double quote" (with {}) the "format" arg to "printf". It'd be nice if neither of these things were necessary.

    I've always believed that "eval" was "evil" and to be avoided if at all possible - both in shell and in Tcl. It has strange side effects, such as
    we see here (the need to "double quote"). Is there any way to get the
    above effect w/o using "eval" ?

    --
    "Every time Mitt opens his mouth, a swing state gets its wings."

    (Should be on a bumper sticker)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Thu Sep 12 19:33:01 2024
    Am 12.09.2024 um 17:07 schrieb Kenny McCormack:
    Consider this (Unix/Linux/bash) command line:

    $ expect -- /dev/fd/3 3<<< 'eval spawn -noecho printf {{\t%s\n}} $argv;interact' $(seq 1 10)

    This correctly generates the output (each line starts with a tab):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    But notice how we have to use "eval" in order to split up the args in $argv. And, since we are using "eval", we have to "double quote" (with {}) the "format" arg to "printf". It'd be nice if neither of these things were necessary.

    I've always believed that "eval" was "evil" and to be avoided if at all possible - both in shell and in Tcl. It has strange side effects, such as
    we see here (the need to "double quote"). Is there any way to get the
    above effect w/o using "eval" ?


    Kenny,
    thanks for the question. Here is the answer by a TCL'er without expect knowledge.

    "eval" does an additional round of substitutions. This happens for all
    elements and is intended, if a whole command is included in a variable.

    To only expand some arguments, the list expansion operator may be used:

    In your case:
    eval spawn -noecho printf {{\t%s\n}} $argv
    equal to:
    spawn -noecho printf {\t%s\n} {*}$argv
    eventually, this works to:
    spawn -noecho printf \t%s\n {*}$argv

    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to [email protected] on Thu Sep 12 18:45:30 2024
    In article <vbv8kd$blsb$[email protected]>,
    Harald Oehlmann <[email protected]> wrote:
    Am 12.09.2024 um 17:07 schrieb Kenny McCormack:
    Consider this (Unix/Linux/bash) command line:

    $ expect -- /dev/fd/3 3<<< 'eval spawn -noecho printf {{\t%s\n}} >$argv;interact' $(seq 1 10)

    This correctly generates the output (each line starts with a tab):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    But notice how we have to use "eval" in order to split up the args in $argv. >> And, since we are using "eval", we have to "double quote" (with {}) the
    "format" arg to "printf". It'd be nice if neither of these things were
    necessary.

    I've always believed that "eval" was "evil" and to be avoided if at all
    possible - both in shell and in Tcl. It has strange side effects, such as >> we see here (the need to "double quote"). Is there any way to get the
    above effect w/o using "eval" ?

    ...
    To only expand some arguments, the list expansion operator may be used:

    In your case:
    eval spawn -noecho printf {{\t%s\n}} $argv
    equal to:
    spawn -noecho printf {\t%s\n} {*}$argv
    eventually, this works to:
    spawn -noecho printf \t%s\n {*}$argv

    Indeed it does. Thanks! This solves my issue.

    ISTM that this {*} thing is a relatively recent addition to the langauge,
    since Expect has been around for a long time, and most of the scripts that
    do this sort of thing were written long ago.

    --
    person woman man camera tv

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Kenny McCormack on Fri Sep 13 04:32:55 2024
    Kenny McCormack <[email protected]> wrote:
    ISTM that this {*} thing is a relatively recent addition to the langauge,

    Not really, it was added in 8.5, which was released Feb 12, 2016 [1].
    Although 2016 *is* relatively recent in regards to many expect scripts.

    since Expect has been around for a long time, and most of the scripts that
    do this sort of thing were written long ago.

    Before 8.5, 'eval' was the way to perform the "splicing" that {*}
    provides.


    [1] https://www.tcl.tk/software/tcltk/8.5.tml

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Harald Oehlmann on Fri Sep 13 04:36:04 2024
    Harald Oehlmann <[email protected]> wrote:
    spawn -noecho printf {\t%s\n} {*}$argv
    eventually, this works to:
    spawn -noecho printf \t%s\n {*}$argv

    Do note that the second one causes \t and \n to be interpreted by Tcl's
    parser, so printf gets passed a literal tab and literal newline in its parameter list. The first passes the \ and t characters on to printf,
    and then printf does the interpretation.

    Both likely work fine for printf, but may not work fine for all
    possible external commands.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Fri Sep 13 08:47:39 2024
    Am 13.09.2024 um 06:32 schrieb Rich:
    Kenny McCormack <[email protected]> wrote:
    ISTM that this {*} thing is a relatively recent addition to the langauge,

    Not really, it was added in 8.5, which was released Feb 12, 2016 [1]. Although 2016 *is* relatively recent in regards to many expect scripts.

    since Expect has been around for a long time, and most of the scripts that >> do this sort of thing were written long ago.

    Before 8.5, 'eval' was the way to perform the "splicing" that {*}
    provides.


    [1] https://www.tcl.tk/software/tcltk/8.5.tml

    Sorry, this date is TCL 8.5.19. The {*} was TCL 8.5.0...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Fri Sep 13 08:21:53 2024
    Am 12.09.2024 um 20:45 schrieb Kenny McCormack:
    ISTM that this {*} thing is a relatively recent addition to the langauge, since Expect has been around for a long time, and most of the scripts that
    do this sort of thing were written long ago.

    "Relatively recent" is quite relative. Here is the relevant changes file
    entry:

    2006-11-02 (feature change)[TIP 293] Replace {expand} with {*} (hobbs)
    *** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***

    ;-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to [email protected] on Fri Sep 13 11:21:07 2024
    In article <vc0f9n$ml8n$[email protected]>, Rich <[email protected]d> wrote: >Kenny McCormack <[email protected]> wrote:
    ISTM that this {*} thing is a relatively recent addition to the langauge,

    Not really, it was added in 8.5, which was released Feb 12, 2016 [1]. >Although 2016 *is* relatively recent in regards to many expect scripts.

    Well, yes, really, from the perspective of Expect.

    That was my point - that Expect hasn't really changed much since the late
    90s, and most of the active development was done then. The scripts that I
    have in mind - such as "unbuffer" - date back to that era.

    since Expect has been around for a long time, and most of the scripts that >> do this sort of thing were written long ago.

    Before 8.5, 'eval' was the way to perform the "splicing" that {*}
    provides.

    Right. OK.

    I'm glad I learned about {*}.

    --
    This is the GOP's problem. When you're at the beginning of the year
    and you've got nine Democrats running for the nomination, maybe one or
    two of them are Dennis Kucinich. When you have nine Republicans, seven
    or eight of them are Michelle Bachmann.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to [email protected] on Fri Sep 13 11:26:10 2024
    In article <vc0ffk$ml8n$[email protected]>, Rich <[email protected]d> wrote: >Harald Oehlmann <[email protected]> wrote:
    spawn -noecho printf {\t%s\n} {*}$argv
    eventually, this works to:
    spawn -noecho printf \t%s\n {*}$argv

    Do note that the second one causes \t and \n to be interpreted by Tcl's >parser, so printf gets passed a literal tab and literal newline in its >parameter list. The first passes the \ and t characters on to printf,
    and then printf does the interpretation.

    Both likely work fine for printf, but may not work fine for all
    possible external commands.


    I think you misunderstand Harald's post (i.e., his notation).

    The point is that if you pass {{\t%s\n}} to "eval", both sets of braces get removed and what "printf" sees is (literally)

    backslash tee percent ess backslash en

    If you only pass a single level of braces, and eval it, then yes, as you
    said, printf will see

    tab percent ess newline

    --
    "Insisting on perfect safety is for people who don't have the balls to live
    in the real world."

    - Mary Shafer, NASA Ames Dryden -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Kenny McCormack on Fri Sep 13 17:24:58 2024
    Kenny McCormack <[email protected]> wrote:
    In article <vc0lm1$npv9$[email protected]>,
    Harald Oehlmann <[email protected]> wrote:
    Am 12.09.2024 um 20:45 schrieb Kenny McCormack:
    ISTM that this {*} thing is a relatively recent addition to the langauge, >>> since Expect has been around for a long time, and most of the scripts that >>> do this sort of thing were written long ago.

    "Relatively recent" is quite relative. Here is the relevant changes file >>entry:

    2006-11-02 (feature change)[TIP 293] Replace {expand} with {*} (hobbs)
    *** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***

    ;-)

    The other poster seemed to think 2016 (not 2006). That's still 8 years ago...

    I pulled a date for a "point version" of 8.5 instead of 8.5.0.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to [email protected] on Fri Sep 13 17:17:46 2024
    In article <vc0lm1$npv9$[email protected]>,
    Harald Oehlmann <[email protected]> wrote:
    Am 12.09.2024 um 20:45 schrieb Kenny McCormack:
    ISTM that this {*} thing is a relatively recent addition to the langauge,
    since Expect has been around for a long time, and most of the scripts that >> do this sort of thing were written long ago.

    "Relatively recent" is quite relative. Here is the relevant changes file >entry:

    2006-11-02 (feature change)[TIP 293] Replace {expand} with {*} (hobbs)
    *** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***

    ;-)

    The other poster seemed to think 2016 (not 2006). That's still 8 years
    ago...

    --
    Republican Congressman Matt Gaetz claims that only ugly women want
    abortions, which they will never need since no one will impregnate them.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)