Any way to store interpolated strings in a ShuffledList?

Hi,

I’m not sure if this is a bug or feature.

When I run the attached program, I get:

I’d expect the last line to be “true”. Is there any way to achieve this?

The program:

#include <adv3.h>

versionInfo: GameID {}

gameMain: GameMainDef {

    myBool = nil;

    myList: ShuffledList {
        ['<<if myBool>>true<<else>>nil<<end>>'];
    }

    showIntro() {
        "myBool is: <<reflectionServices.valToSymbol(myBool)>>\n";
        "<<myList.getNextValue()>>\n";
        myBool = true;
        "myBool is: <<reflectionServices.valToSymbol(myBool)>>\n";
        "<<myList.getNextValue()>>\n";
    }

}

In trying to test your code, I ran into a couple of problems. First, you put a semicolon after myBool=nil – I had to remove that. But now I get a more interesting error:

Having sorted that out, I get the same results you do. Evidently, the evaluation in the string is being stored when the string is created, not each time it’s printed.

Thanks for your reply.

Do you think there is any way to store strings with code in them in a list in such a way so that the code execution is deferred until the time I use the string?

FWIW, using anonymous functions here doesn’t work either, probably because they are implemented as closures which capture and use the original value of variables:

#include <adv3.h>

versionInfo: GameID {}

gameMain: GameMainDef {

    myBool = nil;

    myList: ShuffledEventList {
        [function() {if (myBool) "true\n"; else "nil\n";}];
    }

    showIntro() {
        "myBool is: <<reflectionServices.valToSymbol(myBool)>>\n";
        myList.doScript();
        myBool = true;
        "myBool is: <<reflectionServices.valToSymbol(myBool)>>\n";
        myList.doScript();
    }

}

In the last example, moving myBool out from the local scope seems to do the trick:

#include <adv3.h>

versionInfo: GameID {}

myGlobals: object {
    myBool = nil;
}

gameMain: GameMainDef {

    myList: ShuffledEventList {
        [function() {if (myGlobals.myBool) "true\n"; else "nil\n";}];
    }

    showIntro() {
        "myBool is: <<reflectionServices.valToSymbol(myGlobals.myBool)>>\n";
        myList.doScript();
        myGlobals.myBool = true;
        "myBool is: <<reflectionServices.valToSymbol(myGlobals.myBool)>>\n";
        myList.doScript();
    }

}

Now I get what I want:

myBool is: nil
nil
myBool is: true
true

Again, not sure if it’s a bug or feature.

I tried moving both myBool and the ShuffledList out of GameMainDef, but I put them both in the same object. It didn’t occur to me to try putting them in different objects. Weird … whether it’s a bug or a feature may be a semantic question.

These two code snippets are essentially equivalent:

gameMain: GameMainDef {
  myList: ShuffledList {
    ...
  }
}
anonListObj1: ShuffledList {
  ...
}

gameMain: GameMainDef {
  myList = anonListObj1
}

The “myBool = true” statement in showIntro() is setting self.myBool, but its self is different from the ShuffledList’s self, since they are distinct objects.

“myList.myBool = true” will set the property in the list object instead.