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