variable values within variable values? Thread last updated on 2004-05-18 02:33:21

Posted by member 12025 on 2004-04-10 03:25:16

OK, let's say I have boxes named amp, ampgrip, ampshade, vwmgrip, vwmshade, vwm, etc., and each has x, y, width and height values to work with. I've got several sets of these, all will be using the same methods of setting their display up, just with the module name (and therefor box and label names) being different.
I want to have a single set of !bangs to control this, as it would make life simpler if I could do it.
*script bang !setSize
*script exec !setSize_%{cur_side}
*script ~bang
*script bang !setSize_left
*script exec !LsBoxMoveBox %{cur}Grip 0 0
*script exec !varSet cur_x %{cur}Grip_size
(...)
*script ~bang

!varSet cur "amp"
!varSet cur_side "left"
!setSize

Now, it obviously works up the last line of the setSize_left !bang. Cur_x is set to "ampGrip_size". I kinda figured that would happen.
What I want is for it to be set to the variable of that name. %{%{cur}Grip_size} doesn't work, either.

Is there any way to do this (including saving and reloading variables, so the evars and mzscript vars match up, since I can do what I want with evars), or will I just have to have a monstrous script file with a few lines changed each !bang for what are basically the same !bangs?

With luck there's a very simple way of doing this I'm overlooking.

Posted by member 37809 on 2004-04-10 09:44:40 link

Current v0.9 beta releases of mzscript aren't designed to do it with an intuitive syntax. You have a few choices for current 0.9 versions.
*script exec !varset foo bar
*script exec !varset bar baz

Suppose you want to get "%{%{foo}}", which would be "baz".

The way I stumbled upon by mere luck after trying a few things to fool the mzscript variable expander:
*script exec !varset tmp {%{foo}}
*script exec !varset tmp %%{tmp}

The way I've seen RabidCow do it also involves expanding twice but is done in single line.
;// need this to make mzScript let me do indirection
*script var P %

*script exec !exec !varset tmp %{P}{%{foo}}


So it works by expanding the inner variable name (inside the {}) first, and then expanding the result of that as another variable name.

Posted by member 99 on 2004-04-10 14:30:27 link

iirc, !VarSet does an extra var expansion on its second parameter, so
*script var P
*script exec !VarSet tmp %{P}{%{foo}}
should be enough. (took me a while to realize this) It's pretty rare for an extra !exec to do harm though.

You also get an extra !exec at each script-defined bang call and inside !IfEval. (well, it's almost the same as an extra !exec)

Posted by member 12025 on 2004-04-10 14:47:51 link

OK, works!

Thanks!

Edit: Oh, and one thing I found that kinda got rid of the problem was using !varSaveAll and !scriptLoad. !scriptload works fine in beta 12, but the readme lists it as disabled, so I hadn't tried it before.

Posted by member 12798 on 2004-05-05 11:20:08 link

hey, i can't get this to work:
a mzscript bang gets passed parameters, i want to save these to variables in a way like this
!varset tmp %{\%{counter}}

so that i access the values of \1 and \2 and so on.
it's not really different from the one problem above, but i don't succeed... :(

Posted by member 37809 on 2004-05-05 13:04:30 link

What you have won't work because it is what doesn't work and is what this thread tries to resolve :)

A bang should take a fixed number of arguments if you're using \1, \2, etc, right? Something like this should work:

!varset a1 "%{\1}"
!varset a2 "%{\2}"
...

What you have is too complicated, because there is no variable that stores the number of arguments passed into a bang.

Posted by member 12798 on 2004-05-05 13:49:52 link

thank you for your answer. i thought it couldn't be too complicated, as the docs state: "...and this short example shows that there is no limitations to what can be done with this script according to A. Turing" ;)

well then, i've realised there's an easy workaround for this, as you wouldn't normally pass more than a few arguments...

Posted by member 99 on 2004-05-05 20:49:02 link

!VarSet tmp%{counter} "%{P}{\%{counter}}"
but I don't know how well such a generic thing will work in practice, since you might end up clobbering the parameters again with their tmp names. I've taken to using temp names that include some form of the name of the bang command, and then being very careful not to be recursive.

There was one case where I really needed nested calls, then I provided push/pop macros for those internal variables that the caller could use:
*script bang !ListForEachPush
;{ // !ListForEachPush
*script exec !VarSet %{\1}ListForEachList "%{P}{ListForEachList}"
*script exec !VarSet %{\1}ListForEachItem "%{P}{ListForEachItem}"
*script exec !VarSet %{\1}ListForEachCommand "%{P}{ListForEachCommand}"
*script exec !VarSet %{\1}ListForEachBreak "%{P}{ListForEachBreak}"
*script ~bang
;}

*script bang !ListForEachPop
;{ // !ListForEachPop
*script exec !VarSet ListForEachList "%{P}{%{\1}ListForEachList}"
*script exec !VarSet ListForEachItem "%{P}{%{\1}ListForEachItem}"
*script exec !VarSet ListForEachCommand "%{P}{%{\1}ListForEachCommand}"
*script exec !VarSet ListForEachBreak "%{P}{%{\1}ListForEachBreak}"
*script ~bang
;}

Posted by member 37809 on 2004-05-05 22:33:33 link

RabidCow: "what?" (maybe I don't need to know what that does :)

also, what editor is it you use for that code folding?

Posted by member 99 on 2004-05-06 11:23:28 link

I have a script called "!ListForEach", and as soon as I enter it, I do:
*script exec !VarSet ListForEachList "%{P}{%{\1}}"
*script exec !VarSet ListForEachCommand '%{P}{\2}'
*script exec !VarSet ListForEachBreak "false"
Now !ListForEach calls other bangs internally (supplied as an argument actually...), and in this case one of those may end up calling !ListForEach again. If that happened, the second time it got to
*script exec !VarSet ListForEachList "%{P}{%{\1}}"
*script exec !VarSet ListForEachCommand '%{P}{\2}'
*script exec !VarSet ListForEachBreak "false"
it'd write over the values for the outer call, and when you return to it, things fall apart.

So when I'm in something that I know may be called inside of !ListForEach and I need to call !ListForEach, I use "!ListForEachPush something", call !ListForEach, and then call "!ListForEachPop something" to restore the values for the outer loop. Of course if I needed to nest both functions another level it'd get really messy.

And I'm using SciTE with its "Resource" language lexer. I think alphaedit3 does a better job, but SciTE is nice and lightweight, and I use it for most text editing for everything else anyway.

Posted by member 99 on 2004-05-06 11:24:46 link

Something tells me that's still really confusing, but I only have this tiny textarea box to work with.

Posted by member 12798 on 2004-05-06 13:45:45 link

ok, i don't know if i'm ever going to understand this, but thank you very much anyway.

this is something to praise you and to show me appretiation: http://www.uni-weimar.de/~liebsch/stuff/lotm.jpg ;D

Posted by member 99 on 2004-05-06 22:30:35 link

lol, thank you :)

If you can avoid recursion or nested calls to the same script, using something like
!VarSet ScriptBangName1 "%{\1}"
!VarSet ScriptBangName2 "%{\2}"
should work fine, and you wouldn't have to worry about the push/pop stuff.

Posted by member 12798 on 2004-05-09 14:23:03 link

hm, i've found the time to try ...
*script exec !VarSet tmp%{counter} "%{P}{\%{counter}}"
sets the value of tmpn to {\n} ( {\1} for tmp1 etc.), instead of the evaluation of \1 ... :/

Posted by member 12025 on 2004-05-09 14:34:24 link

(a backslash won't display, I don't feel like figuring out why)
*script exec !varSet s ""
*script exec !varSet tmp%{counter} %{P}{%{s}%{counter}}
or maybe
*script exec !varSet s ""
*script exec !varSet tmp %{s}%{counter}
*script exec !varSet tmp%{counter} %{P}{%{tmp}}

Posted by member 12798 on 2004-05-09 15:50:23 link

either it doesn't work, or there's so strangeness in how mzscript/ls evaluate vars... because i had some hints on that they are handled the right way internally. however, i can't really figure out at the moment, because the whole theme is a real mess and i don't really know myself what i'm doing :D

Posted by member 12025 on 2004-05-09 17:13:09 link

It could be the theme, maybe...?
I just wrote this up, and it worked fine. Chnaging the value of counter changed the parameter it finally set tmp2 to (IE, it worked).
*script bang !ev
*script exec !varSet P "%"
*script exec !varSet counter 1
*script exec !varAdd counter 1 ; change param to simulate looping w/o working at it
*script exec !varSet tmp %{P}{\%{counter}}
*script exec !varshow tmp
*script ~bang
I know the them being a mess bit...I broke mine yesterday, almost done, and found the root cause would require over a dozen boxes and around 100 script lines changed...starting over from scratch :). Luckily the RCs aside from scripting will copy and paste over pretty well.
(edit: spelling)

Posted by member 12798 on 2004-05-09 17:39:26 link

wheee - it works! thank you a thousand times! not that my theme now does anything like it should, but basically this should only be a question of time and concentration (doh! ;D ).

i had missed the "%" in the P var, because RabidCow did not have it in his code... one small % for a man, but a huge step for my theme :)

hm... maybe i should move my lazy a** over to irc from time to time :D ... would probably speed things up pretty often (as you can see, this problem now already lasts since nearly one week, where i've spend hours and hours wasting my time...).

Posted by member 12798 on 2004-05-10 11:58:38 link

just wanted to say - i've got it done :) everything works as expected.
thanks again, Cerbie and RabidCow - you've won a note in the theme's readme, given that it will ever be published... :D

Posted by member 99 on 2004-05-10 22:34:09 link

oops, how did I leave out the %?

Posted by member 12798 on 2004-05-17 19:24:31 link

another question (sorry guys, expect me to finish this in a year or two ;) ): how can i write the value of this
%{P}{tmpv%{currlevel}1}
to a file?

this does not work, it saves the var name instead of the content:
!textappend @%#ConfigDir%#x.rc@ @"%{P}{tmpv%{currlevel}1}"@
i've looked through several themes, but i couldn't find anything helpful...

Posted by member 12025 on 2004-05-17 19:28:47 link

%{P}{tmpv%{currlevel}1}
Will only reliably work for !varSet. I've tried it elsewhere, no luck, but sometimes seems to work on the left side of a GotoIf. Overall better to have preceeding !varSet lines and be safe (IMO).
So add a line or two so that you have a single %{var} in the !textAppend bang.

Posted by member 12798 on 2004-05-17 19:41:39 link

doh, sometimes all this totally confuses your mind so you don't even think of an easy solution like that :D
thanks again, and be sure this thread won't be quiet for long :P

Posted by member 99 on 2004-05-18 02:33:21 link

!varSet does an extra var expansion, !textappend does not. If you want to use %{P}{...} for anything that's not built in to mzscript (and some things that are), you need to add an extra !exec to the start of the line.

*script exec !varSet currlevel ABCD
*script exec !textappend @%#ConfigDir%#x.rc@ @"%{P}{tmpv%{currlevel}1}"@
is expanded once by mzscript to
!textappend @$ConfigDir$x.rc@ @"%{tmpvABCD1}"@


*script exec !varSet currlevel ABCD
*script exec !varSet tmpv%{currlevel}1 EFGH
*script exec !exec !textappend @%#ConfigDir%#x.rc@ @"%{P}{tmpv%{currlevel}1}"@
is expanded first to
!exec !textappend @$ConfigDir$x.rc@ @"%{tmpvABCD1}"@
and then again with !exec to
!textappend @$ConfigDir$x.rc@ @"EFGH"@


Actually, there is a possibility that something in $ConfigDir$ will screw up here, but paths with %s in them are pretty rare.