Looking for a cure for weird scope/memory of variables
Gustaf Neumann
neumann at wu.ac.at
Tue Jul 16 12:44:16 PDT 2013
Am 16.07.13 20:18, schrieb Mojca Miklavec:
>> In general, the better strategy seems to for me to avoid the
>> definition-time substitutions of the subport body at all.
>> This could be achieved with an associative array
>> indexed by the version numbers. When we have an array
>>
>> array set foo {
>> 1.1,version "bla 1"
>> 2.0,version "bla 2"
>> }
>>
>> and we assume, the subport version number is available
>> at the execution time of "pre-fetch" etc. as global
>> variable "subport", one could use the following:
>>
>>
>> foreach {foo.version foo.string} ${foo.versions} {
> What exactly is foo.versions in this case? I guess that foo.version
> and foo.string are the variables defined by "foreach" loop.
yes, ${foo.versions} is the same as in the versions before.
>> subport foo-${foo.version} {
>> pre-fetch {
>> system "echo $foo($subport,version)"
> Subport is foo-1.1 or foo-2.0, right? Where does version come from and
> what is it? What is $foo($subport,version)?
The value of the associative array "foo" with the key "$subport,version"
above.
By providing all configure information in a global associative
array, the loop might not be necessary at all
> Anyway, this seems cleaner to me than the hack with eval (even if I
> don't understand it yet).
... at least, under the assumption, that $subport is set always correctly...
as vq points out, the value could be easily extracted from the version...
but macports should do this IMHO, not the Portfile author.
>> With tcl 8.5 or newer, dicts are another option:
> What does that mean for MacPorts? Could they be used in Portfiles or not (yet)?
currently, MacPorts depends on the version of tcl shipped by apple.
If i see correctly, MacPorts supports Tiger or newer.
According to http://www.python.org/getit/mac/tcltk/, the following versions
of tcl are shipped by Apple:
10.4 (tiger): Tcl 8.4.7,
10.5 (leopard): Tcl 8.4.7
10.6 (snow leopard): Tcl 8.4.19, Tcl 8.5.7
10.7 (lion): Tcl 8.4.19, Tcl 8.5.9
10.8 (mountain lion): Tcl 8.4.19, Tcl 8.5.9
so, dict can be used with the snow leopard or newer (not sure, where the
default tclsh is liked to).
With Tcl 8.5 bundled with MacPorts, dict would be available on every
version.
>> set foo.dict [dict create \
>> 1.1 { version "bla 1"
>> path "xxx"} \
>> 1.2 { version "bla 2"
>> path "yyy"}]
>>
>>
>> foreach {foo.version foo.string} ${foo.versions} {
> What is foo.versions again?
same as above
>
>> subport foo-${foo.version} {
>> pre-fetch {
>> system "echo [dict get ${foo.dict} $subport version]"
> May I ask for a bit of explanation for this one as well?
a "dict" is a tree data-structure introduced by tcl 8.5. In contrary to
associative arrays, dicts are values, can be easily passed around in
arguments, can be assigned to variables. A dict can be created via "dict
create", or it can be converted on the fly by dict commands into
appropriate Tcl_Objs. Look at the following example. We start the
tclsh an set a variable with a list with key/value pairs.
$ tclsh
% set d {1.1 {a 10 b 20} 1.2 {a 100 b 200}}
1.1 {a 10 b 20} 1.2 {a 100 b 200}
When we want to access a value from the dict, we can use "dict get".
This command gets as argument a dict structure (our list) and converts
it to the internal strucutre of the dict (a hash table) and returns the
value for the key 1.1
% dict get $d 1.1
a 10 b 20
Similarly we can access values deeper in the structure by passing
multiple arguments.
In the next line, we get value for key "a" in the dict, returned by the
key "1.1"
% dict get $d 1.1 a
e
% dict get $d 1.2 b
200
You find probably better tutorials for tcl dicts on the web.
The idea of the snippet above is to use a global variable (e.g. foo.dict)
with all the config variables for all subports, such one can use
$subport for accessing the dict values
% dict get $d $subport SOMEKEY
Does this make things clearer?
All the best
-gustaf
More information about the macports-dev
mailing list