+1 vote
by (130 points)

I have something similar to the following in my code:

<<set _toPrint = []>>

<<for _index = 0; _index < 5; ++_index>>
    <<set _myValue = random(1,5)>>
    <<set _toPrint[random(1,4)] = "The value is _myValue">>
    <<unset _myValue>>
<</for>>

<<for _index = 0; _index < 4; ++_index>>
    <<if def _toPrint>>
        <<print "For _index: " + _toPrint[_index]>>
    <</if>>
<</for>>

However, when I run this, it says, for example, "For 0: The value is _myValue". If I print at the time I set it, it says "The value is 3". If I remove the unset, it will say the last value for all of them.

I need to take the value at the time I store it into the array, and I can't use javascript appends (the string is stored someplace else where the variables aren't set yet)

I've tried everything I can think of: clone, toString, capture, remember, <<print "<<set value=\"" + _theValue + "\">>">>. How do I flatten the string?

1 Answer

0 votes
by (63.1k points)
I don't understand what you're trying to do or what the goal here is.  That might be on me, but I need you walk me through this one.  What's the goal here?  What are you trying to get to happen?
by (130 points)
edited by
The goal is that in a separate file I have a list of, say, items. These items are defined as "{name:'Sentient Sword', type: 'sword', description:'It looks at you and says, "Hello $playername!"}". Later, in the presentation code, it takes all the items, sorts it into a list of lists, like '_itemGroup[_item.type].push("You have _item.name -- _item.description"'), then, once everything is grouped, print out each group in order with their group titles. At that time, the variables no longer exist. If I print during the sorting loop, it shows "You have Sentient Sword -- It looks at you and says 'Hello Bob!'" in a random position among the rest of the unsorted items. But if I do it in the presentation, when I put in a group title and place everything in their groups, if I've unset _item, it shows "You have _item.name -- _item.description". If I don't unset _item, then, every item under the every heading, including the "sword" heading where Sentient Sword is, it says "You have an apple -- it's a golden delicious.", because it was the last item in the list. I've since solved it for now by using a function that uses $(temp).wiki to flatten it into a temporary div and return the HTML from that, but I would like to know if there's a built-in way.
by (159k points)

<<set _toPrint[random(1,4)] = "The value is _myValue">>

The _myValue variable in the above String value is not evaluated until the String is printed within the second <<for>> macro, which is why the printing of each of the Strings in the _toPrint array all show the same output.

Changing the above line of code to something like the following should fix your issue:

<<set _toPrint[random(1,4)] = "The value is " + _myValue>>

 

by (130 points)
edited by

Right, the variable no longer exists when it finally tries to print, so I need a way to capture the result and store it, to flatten the string.

I can't switch to javascript concatenation because the string actually comes from somewhere else. Say:

<<set $toPrintVariance = ["The value is _myValue", "_myValue is the value", "For the value, you would find _myValue"]>>
<<set $toPrint = {}>>
<<set $items = [{type: "sword", value: "dagger"}, {type:"food", value:"apple"}, {type: "sword", value: "broadsword"}, ]>>
<<for _i = 0; _i < $items.length; ++_i>>
    <<set _item = $items[_i]>>
    <<set _myValue = _item.value>>
    <<if ndef $toPrint[_item.type]>>
        <<set $toPrint[_item.type] = []>>
    <</if>>
    <<run $toPrint[_item.type].push($toPrintVariance.random())>>/* Need to flatten here */
<</for>>

<<set _toPrintCategories = Object.keys($toPrint)>>
<<for _i = 0; _i < _toPrintCategories.length; ++_i>>
    <<set _category = _toPrintCategories[_i], _values = $toPrint[_category]>>
    <h2>_category</h2>
    <ul>
    <<for _iPrint = 0; _iPrint < _value.length; ++_iPrint>>
        <<set _printValue = _values[_iPrint]>>
        <li>_printValue</li>
    <</for>>
    </ul>
<</for>>

In this case, without flattening, I would have:

sword
The value is apple
For the value, you would find apple
food
apple is the value

When what I want is:
sword
The value is dagger
For the value, you would find broadsword
food
apple is the value

My workaround was to create a flatten() function that I put  on the line with the comment. It's not perfect -- Links don't survive, for example -- but it's better than nothing.

by (159k points)

If I understand your issue correctly wouldn't replacing the following line in your last example:

<<run $toPrint[_item.type].push($toPrintVariance.random())>>/* Need to flatten here */

... with something like the following which uses the Javascript <String>.replace() method solve your issue:

<<set _val to $toPrintVariance.random().replace("_myValue", _item.value)>>
<<run $toPrint[_item.type].push(_val)>>

warning: The above example was written from memory and has not been tested, so it may contain syntax errors.

by (130 points)

No, that will not work because I put up a simple example to illustrate the problem, not my actual code. My actual code includes "$player.stats.strength", "_activeItem.name", "<<print $player.inventory[_i].effects[_j].name>>", and more. All of which work fine using the wikifier in a javascript function, but would be near impossible to do with a replace function. For example,

<<set _item.description = "_activeItem.name will increase your strength from $players.stats.strength to <<print $players.stats.strength + _activeItem.strengthBoost>>.">>

 

...