declaring variants/subports in loops and loop variables
René J.V. Bertin
rjvbertin at gmail.com
Wed Dec 7 18:32:14 CET 2016
On Wednesday December 07 2016 17:56:56 Brandon Allbery wrote:
> It won't, but that's the best you will do in a stringy language like Tcl
> (or shells, for that matter).
Fortunately there's also the alternative of using an if construct inside the loop, which does work as expected.
> > Not "which ones", just `uplevel 1 $code`, just like `proc platform` does.
> >
>
> I don't think that will work; you're looking for a closure here where $pv
> and $pdv are captured from where the variant is declared, and any other $s
> are either local or uplevel-ed to where the variant is *run* from.
In this case it indeed won't work because $code is not evaluated immediately inside `proc variant` but is instead used to create a procedure that's invoked if the user activates a variant. I haven't tried to figure out exactly how that happens, but apparently it's after the loop has terminated. Probably after the initial parsing run of the Portfile:
{{{
foreach pdv ${pythonversions} {
set pv [join [lrange [split ${pdv} .] 0 1] ""]
variant python${pv} conflicts ${conflist} description "Add bindings for Python ${pdv}" {
ui_msg "variant ${pv} is being defined"
}
# settings that depend on loop variables must be set in an appropriate if, not in the
# variant declaration scope.
if {[variant_isset python${pv}]} {
ui_msg "variant_isset ${pv}"
}
}
#snip
ui_msg "done"
<EOF>
}}}
{{{
%> port info opencv +python34
variant_isset 34
done
variant 35 is being defined
opencv @3.1.0_6 (graphics, science)
}}}
Now I also understand other idiosyncrasies I've run into and resolved by moving expressions from the variant "body" to scopes conditional on variant_isset in order to be certain of the evaluation order.
Cf. a procedure I defined for those of my KF5 ports that need a variant to co-install with their KDE4 counterpart (https://github.com/RJVB/macstrop/blob/master/_resources/port1.0/group/kf5-1.1.tcl#L697). Not relevant for the initial thread topic, just something that gives a clean way to declare a variant as well as code to be executed when the variant is set or when it's not, in such a way that the code can assume that the current state corresponds to what can be inferred from the location in the Portfile.
R
More information about the macports-dev
mailing list