From: scottdware on
So, I'm fairly new to Tcl, and I really love the language. As I've
been learning about it (through online tutorials, manuals, and books),
I've come across the eval function, and the {*} function/command
(expand).

I am reading the book "Tcl and the Tk Toolkit," and in one of the
chapters, it almost seems like using eval would be better practice.
I'm just looking for some clarification, but can you tell me if that
is true, and/or when might be the best time to use one or the other?

Thanks!
From: Bruce on
scottdware wrote:
> So, I'm fairly new to Tcl, and I really love the language. As I've
> been learning about it (through online tutorials, manuals, and books),
> I've come across the eval function, and the {*} function/command
> (expand).
>
> I am reading the book "Tcl and the Tk Toolkit," and in one of the
> chapters, it almost seems like using eval would be better practice.
> I'm just looking for some clarification, but can you tell me if that
> is true, and/or when might be the best time to use one or the other?
>
> Thanks!

if you can use {*} to solve the issue then use it - you can use eval
(as that was all we had for most of history) but there are subtle tricky
gotchas that can sneak up and bite you, which was why the {*} was added
to handle the 90+% of uses of eval without the pain. There are some
cases where list expansion isn't the problem so there are still some
use cases of eval that exist.

bruce
From: miguel sofer on
scottdware wrote:
> So, I'm fairly new to Tcl, and I really love the language. As I've
> been learning about it (through online tutorials, manuals, and books),
> I've come across the eval function, and the {*} function/command
> (expand).
>
> I am reading the book "Tcl and the Tk Toolkit," and in one of the
> chapters, it almost seems like using eval would be better practice.
> I'm just looking for some clarification, but can you tell me if that
> is true, and/or when might be the best time to use one or the other?
>
> Thanks!

First, let's talk about expansion. [eval] does uncontrolled expansion of
every argument: you have to protect things you do not want expanded
using [list]. Ie, it is "default expand, mark the exceptions". {*} only
expands its 'arguments'.

In general I think you are better advised to use {*}; the use of
uncontrolled expansion forces you to think about all possible misshaps;
it is the source eg of many of the "does not work if the file name has a
space" bugs.

Now safety. An IMPORTANT additional feature of [eval] is that it
evaluates on top of expanding. So you have to list-protect also things
that could have '[..]' in them in order to avoid unwanted execution.

Think of something that is input by the user, say "[exec rm -rf /*]".
Safe to {*}, dangerous to eval ...

HTH
Miguel
From: Arjen Markus on
On 12 mei, 15:07, scottdware <scottdw...(a)gmail.com> wrote:
> So, I'm fairly new to Tcl, and I really love the language. As I've
> been learning about it (through online tutorials, manuals, and books),
> I've come across the eval function, and the {*} function/command
> (expand).
>
> I am reading the book "Tcl and the Tk Toolkit," and in one of the
> chapters, it almost seems like using eval would be better practice.
> I'm just looking for some clarification, but can you tell me if that
> is true, and/or when might be the best time to use one or the other?
>
> Thanks!

In general, if (and really if) you need eval's functionality, you
are probably better off with {*}. Here is an example:

eval exec $cmd

works, but _only_ if the elements in $cmd do not contain spaces.
This is because $cmd is replaced by the string value of cmd and
therefore
a "list level" is lost. There are tricks to get it right again, but
they are complicated. (Being a long-time user of Tcl, I still have
to reconstruct the proper, foolproof invocation and won't try it now.)

Using the expansion operator, you can use:

exec {*}$cmd

and as {*} respects the elements of the list, it expands the
command in the right way.

It is akin to (not my invention, just my paraphrase):

- Put a sign on the door of the toilet to say it is a toilet (that is:
use {*})
- Or put a sign on every door that is NOT the door to the toilet to
say that
it is not the toilet (that is: use eval)

Regards,

Arjen

From: scottdware on
On May 12, 10:03 am, Arjen Markus <arjen.markus...(a)gmail.com> wrote:
> On 12 mei, 15:07, scottdware <scottdw...(a)gmail.com> wrote:
>
> > So, I'm fairly new to Tcl, and I really love the language. As I've
> > been learning about it (through online tutorials, manuals, and books),
> > I've come across the eval function, and the {*} function/command
> > (expand).
>
> > I am reading the book "Tcl and the Tk Toolkit," and in one of the
> > chapters, it almost seems like using eval would be better practice.
> > I'm just looking for some clarification, but can you tell me if that
> > is true, and/or when might be the best time to use one or the other?
>
> > Thanks!
>
> In general, if (and really if) you need eval's functionality, you
> are probably better off with {*}. Here is an example:
>
> eval exec $cmd
>
> works, but _only_ if the elements in $cmd do not contain spaces.
> This is because $cmd is replaced by the string value of cmd and
> therefore
> a "list level" is lost. There are tricks to get it right again, but
> they are complicated. (Being a long-time user of Tcl, I still have
> to reconstruct the proper, foolproof invocation and won't try it now.)
>
> Using the expansion operator, you can use:
>
> exec {*}$cmd
>
> and as {*} respects the elements of the list, it expands the
> command in the right way.
>
> It is akin to (not my invention, just my paraphrase):
>
> - Put a sign on the door of the toilet to say it is a toilet (that is:
> use {*})
> - Or put a sign on every door that is NOT the door to the toilet to
> say that
>   it is not the toilet (that is: use eval)
>
> Regards,
>
> Arjen

Thank you all for the replies! This helps out a lot! I like some of
the analogies, also LOL!