modern Tcl and correct quoting
Poor Yorick
org.macosforge.lists.macports-dev at pooryorick.com
Thu Jun 13 06:42:31 PDT 2013
On Thu, Jun 13, 2013 at 08:43:07PM +1000, Joshua Root wrote:
> On 2013-6-13 14:07 , Poor Yorick wrote:
> > Here's another example from the patch. The original version looks like this:
> >
> > if {[catch {eval curl fetch $verboseflag {$source} {$tarpath}} error]} {
> > ...
> > }
> >
> > Taking a look at just the [eval] part:
> >
> > eval curl fetch $verboseflag {$source} {$tarpath}
> >
> > The curly brackets around {$source} and {$tarpath} are there to escape
> > substitution as Tcl prepares to invoke [eval], and this is not necessarily
> > incorrect, but there are some caveats. $verboseflag is resolved prior to the
> > invocation of [eval], but $source and $tarpath are passed as literal strings.
> > If $verboseflag is "yes", [eval] will get exactly five values as arguments:
> >
> > curl
> >
> > fetch
> >
> > yes
> >
> > $source
> >
> > $tarpath
> >
> > It will then concatenate these arguments into a script which it will then pass to the interpreter:
> >
> > curl fetch yes $source $tarpath
> >
> > $source and $tarpath have not been resolved yet. As it prepares to execute
> > [curl], the the interpreter will resolve them, and [curl] will receive exactly
> > 4 arguments.
>
> $verboseflag is actually either empty or "-v". The intent of the
> existing code is that curl will get only 3 arguments when $verboseflag
> is empty. If it weren't for this, the eval could be omitted entirely, right?
>
> So actually using list will change the behaviour by passing the empty
> string as an arg.
>
In that case, the original code is correctly employing double substitution,
exactly as you describe. It could also be written like this:
eval curl fetch $verboseflag {$source $tarpath}
Or, some microseconds could be shaved by avoiding eval:
if {$verboseflag eq {}} {
curl fetch $source $tarpath
} else {
curl fetch $berboseflag $source $tarpath
}
If we weren't writing to Tcl 8.4, we could do this:
curl {*}$verboseflag $source $tarpath
--
Yorick
More information about the macports-dev
mailing list