Looking for a cure for weird scope/memory of variables

Gustaf Neumann neumann at wu.ac.at
Tue Jul 16 13:47:01 PDT 2013


Am 16.07.13 20:50, schrieb Lawrence Velázquez:
> I don't see this extending cleanly to multiple substitutions (which Mojca is doing in the actual Portfile), since you're only allowed one value per array key. I suppose you could have something like this:
>
>      array set foo {
>          foo-1.1,val1 "abc"
>          foo-1.1,val2 "def"
>          foo-2.0,val1 "ijk"
>          foo-2.0,val2 "xyz"
>      }
yes. this was the idea of using the array like notation with the ",".
Sorry that i did not express this more explicitly, thought this was 
obvious.
>
> and use $foo($subport,val1) and $foo($subport,val2) as necessary in the pre-fetch script:
>
>      subport foo-${foo.version} {
>          pre-fetch {
>              system "echo $foo($subport,val1)"
>              system "echo $foo($subport,val2)"
>          }
>      }
>
> Frankly, the pre-fetch script starts to get very ugly at this point. The benefit of the "string map" substitution route is that the actual script is the same as it would be otherwise; it just gets wrapped in some eval wand-waving.
hmm, how can you say this: The "string mapping" is potentially more 
error prone when it comes to quoting.

Look at the slightly extended example here, where two attributes 
("param" and "title"), are used, where the "title" should be passed as 
well as argument of some function "f1":

    set foo.versions {
        2.0 x "hello world"
        3.0 y {$x [foo]; 1}
        4.1 z ""
     }

     foreach {foo.version foo.param foo.title} ${foo.versions} {
         set script {
             subport foo-${foo.version} {
                 pre-fetch {
                     system "echo ${foo.param}"
                     system "echo ${foo.title}"
                     f1 ${foo.title}
                 }
                 fetch {}
                 extract {}
                 use_configure no
                 build {}
                 destroot {}
             }
         }
         set script [string map [list \
                \${foo.param} [list ${foo.param}] \
                \${foo.title} [list ${foo.title}] \
              ] $script]
         eval $script
     }

The string map command gets longer, the more subvalues are needed.
Note, the "string map" has a list wrapper for the value ([list 
${foo.param}]),
as you suggested. As a consequence, the output of "echo" will have
some curly brackets, which might be harmful. If no list wapper
is used, the "echo" will be ok for the first value (without braces),
but the later values will run into problems, and so does
"f1".

it is certainly possible to find notations for the usages of the values 
that work
with and without the wrapper, but the code will get even uglier, more
fragile ... (imho).

Here is the array version with two variables

    set array foo {
        foo-2.0,param x
        foo-2.0,title "hello world"
        foo-3.0,param y
        foo-3.0,title {$x [foo]; 1}
        foo-4.1,param z
        foo-4.1,title ""
     }

     foreach {foo.version} {foo-2.0 foo-3.0 foo-4.1} {
         subport foo-${foo.version} {
             pre-fetch {
                 system "echo $foo($subport,param)"
                 system "echo $foo($subport,title)"
                 f1 $foo($subport,title)
             }
             fetch {}
             extract {}
             use_configure no
             build {}
             destroot {}
         }
     }

... and the dict version ....

    set cfg {
        foo-2.0 {param x title "hello world"}
        foo-3.0 {param y title {$x [foo]; 1}}
        foo-4.1 {param z title ""}
    }

     foreach {foo.version} [dict keys $cfg] {
         subport foo-${foo.version} {
             pre-fetch {
                 system "echo [dict get $cfg $subport param]"
                 system "echo [dict get $cfg $subport title]"
                 f1 [dict get $cfg $subport title]
             }
             fetch {}
             extract {}
             use_configure no
             build {}
             destroot {}
         }
     }


All scripts are untested, and have probably typos etc....
but i would not expect much surprises form the last two version
(aside of the setting of the global vars such as $subversion).

all the best
-g



More information about the macports-dev mailing list