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

Reply via email to