Looking for a cure for weird scope/memory of variables

Mojca Miklavec mojca at macports.org
Tue Jul 16 11:18:54 PDT 2013


Dear Gustaf,

(I'm still) processing, please wait ... ;)

On Sat, Jul 13, 2013 at 8:48 PM, Gustaf Neumann wrote:
> Am 10.07.13 00:25, schrieb Lawrence Velázquez:
>
>> For selective definition-time substitution, you could use string map
>> (http://wiki.tcl.tk/37332#pagetoc04c6ab3f):
>>
>>      foreach {foo.version foo.string} ${foo.versions} {
>>          set script {
>>              subport foo-${foo.version} {
>>                  pre-fetch {
>>                      system "echo ${foo.version}"
>>                  }
>>                  fetch {}
>>                  extract {}
>>                  use_configure no
>>                  build {}
>>                  destroot {}
>>              }
>>          }
>>          set script [string map [list \${foo.version} [list
>> ${foo.version}]] $script]
>>          eval $script
>>      }
>
>
> This can be done slightly better (note, on the first argument of "string
> map",
> the inner "list" is not necessary)
>
>
>     foreach {foo.version foo.string} ${foo.versions} {
>
>         eval [string map [list \${foo.version} ${foo.version}] {
>
>             subport foo-${foo.version} {
>                 pre-fetch {
>                     system "echo ${foo.version}"
>                 }
>                 fetch {}
>                 extract {}
>                 use_configure no
>                 build {}
>                 destroot {}
>             }
>         }]
>
>     }
>
> 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.

>         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)?

>             }
>             fetch {}
>             extract {}
>             use_configure no
>             build {}
>             destroot {}
>         }
>       }
>     }
>
> This works, since the bodies of "pre-fetch" etc. see all
> global variables including the associative array.

Anyway, this seems cleaner to me than the hack with eval (even if I
don't understand it yet).

> 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)?

>     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?

>         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?

>             }
>             fetch {}
>             extract {}
>             use_configure no
>             build {}
>             destroot {}
>         }
>       }
>     }

Thank you and sorry for the beginner's trivial questions.

Mojca


More information about the macports-dev mailing list