Looking for a cure for weird scope/memory of variables

Gustaf Neumann neumann at wu.ac.at
Sat Jul 13 11:48:19 PDT 2013


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} {

         subport foo-${foo.version} {
             pre-fetch {
                  system "echo $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.

With tcl 8.5 or newer, dicts are another option:

     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} {

         subport foo-${foo.version} {
             pre-fetch {
                  system "echo [dict get ${foo.dict} $subport version]"
             }
             fetch {}
             extract {}
             use_configure no
             build {}
             destroot {}
         }
       }
     }


all the best,

-g



More information about the macports-dev mailing list