Variable expansion

I've been having a lot of problems with processing text that contains percent signs, and it seems to me that the problem is with the %! operator. To recap:

%foo%: Expands to whatever "foo" contains, recursively expanding variable references. If there are any single % signs, it fails.

%!foo%: Expands to whatever "foo" contains, but doesn't recurse. Tolerates single % signs.

%%foo%%: Doesn't expand: treated as the literal string: "%foo%'.

 

What I don't really get is why recursive expansion is the default. It's very rare that you'd want to have a variable containing another unexpanded variable reference - it's never happened to me yet. And if you don't want to expand it, but have strings containing arbitrary % signs, you have a major pain in the arse: every time you process such a string, you either have to double it before hand or make sure you use "%!...%" rather than "%...%". And the worst part is that you can have a project which works perfectly on normal input, then one day you process a string which happens to contain a % sign, and suddenly it explodes.

If the default was the other way, it would make more sense: you could happily manipulate a string containing a variable reference, then the one time that you actually want to expand it, you could use a special operator. In practice, you're more likely to use some other kind of placeholder, then simply search/replace that placeholder to substitute it for the real value.

Could we perhaps have an option to make the default to *not* recursively expand?

Sorry for the rant, but this has been giving me serious headaches. Try doing a find-replace involving subexpressions, where the subexpression may contain a percent sign...ugh.

Steve

 

Grr, found another really annoying situation:
Let’s say A contains the following text: 43%
We now want B to contain that text.

Try: “Set variable” B, new value: %A%
That doesn’t work, as it tries to expand the the contents of A as well as the expression “%A%”.

Try: “Set variable” B, new value: %!A%
That doesn’t work, no such variable !A

Try: “Set variable” B, new value: %A%, uncheck “expand expression”
That doesn’t work, B now contains: %A%. Then you’d be really stuffed, as you’d have to somehow expand one layer of referencing, without expanding the next one.

Try: Text find/replace % in A, then do it.
Problems: the expandlogtitle falls over again
Problems: Now A is doubled, but the next time any processing occurs, it will be single again.


This is so painful. Please an option to turn off recursive variable expansion?

Steve

Ok, that’s bizarre, even doubling the % sign, the set variable step still failed.

I gave up. Script Editor: B=A. Bleh.

Steve

Hi Steve

Recursive expansion is on by default for a reason, as it allows you to build variables that are based on the values of other variables. I just tried your example and it worked fine for me. I set the default value of A to 43%% and then set variable B to %!A% in the set variable action. This worked fine.

Changing the behavior of variable expansion now would break so many users projects. Even an option is not a good idea imho, as it would introduce a support nightmare (each variable expansion support request would require an extra round trip to get the users options settings…).

If there is a specific action where expansion should be turned of then let us know, we already have that option in several places.

Recursive expansion is on by default for a reason, as it allows you to build variables that are based on the values of other variables.

If that’s the case, why have macro variables? I thought the idea of a macro variable is that you can have ProjDir that contains “%Drive%%Dir%”, and it expands every time. That makes sense. But why should normal variables do it?

>I just tried your example and it worked fine for me. I set the default value of A to 43%% and then set variable B to %!A% in the set variable action.

I confess, I didn’t think of using a double % and the ! anti-dereferencing operator together. That does indeed work. You do have the problem I described earlier though: A now contains 43%% and B contains 43%. Despite you having just performed the equivalent of A=B.

>If there is a specific action where expansion should be turned of then let us know, we already have that option in several places.

The problem is partially that the options are “off” or “infinite”, where what you probably want is “once”. When I set A=%B%, I neither want A to contain “%B%”, nor that it falls over if B contains a percent sign. I want it to contain a literal copy of the contents of B.

That said, it would be useful on the “find string” page of Text Find / Replace.

Also, it would be really appreciated if actions did not fall over at runtime when their action log titles can’t expand. Whether the action logs as “Set Variable A to %B%” or “Set Variable A to 43%” is not too important. But if that single percent sign breaks the build due to a logging issue, well that’s just too annoying for words.

>Even an option is not a good idea imho, as it would introduce a support nightmare (each variable expansion support request would require an extra round trip to get the users options settings…).

IMHO it shouldn’t be a user option, it should be a project option, as it affects the semantics of that project. I’m not sure what you mean by “support” in this context.

The extra workload in correctly processing % signs all the way through a project that does a lot of text manipulation is pretty big. Pretty much the only reasonable way to handle it is to immediately replace every % sign that comes from input with some other string, then replace them all back at output time. It’s especially irksome since I never use embedded variable references, and I’d be happy to just turn them off altogether. :frowning:

Steve

Hey, I just found another one: apparently the string “$()” triggers some kind of variable expansion as well. I thought I’d sidestepped all my variable expansion nightmares by manually replacing every % in the input file, but sadly not. It seems to be almost undocumented as well, there’s just a reference to it in the FAQ.

Are there any other magic strings I need to check for to stop my builds exploding?

(If there was a way to totally switch off this kind of variable expansion, that would be great.)

Steve

And out of curiosity, is there a way to escape the $() notation? It doesn’t seem possible to do a straight Text Replace to get rid of it, because the search string contains $(), which is expanded at runtime…

Though having said that, I realise a regular expression will work: $()

Steve

Hi Steve

To escape the $(Variable) format, just add another $ in front of it, e.g $$(Variable)

Hi Steve

I just checked the help file, there is a topic about escaping variable characters in there… not sure if it is in the current release (as you know the help has had some work done on it in recent weeks) but it is in the latest test build.

>To escape the $(Variable) format, just add another $ in front of it, e.g $$(Variable)

That's a bit trickier to do on arbitrary text. For the viewers at home, here are the two steps required:

1) Replace "%%" with "%%" (uncheck "Expand variable names in replacement string")

2) Replace \$\(([^)]*)\) with "$$($1)" (uncheck that box, but check "Substitute regular expression matches...").

Steve

PS I would have used the regexp \$(\([^)]*\)) and replaced with $$$1, but that didn't work, as the regexp itself then contains the string $(...).

[