Can arrays be used in Beanshell expressions?

Apparently Beanshell can use arrays, but can they be used in Beanshell expression? I have fiddled around with various ways of initialising a Beanshell array (using Java syntax), but all I get is “Expression Evaluation Error” when trying to use report on one of the cells.

While Beanshell is implemented on an underlying Java Interpreter that does support arrays, the way that Vassal uses Beanshell means that not all Java functionality has meaning or can be used.

Each Beanshell ‘fragment’; is wrapped in a function to return a value, there is no way to ‘set’ an underlying Java value, and even if you did, that value would be thrown away as soon as the Beanshell fragment finishes executing.

You can emulate arrays using Global Propertiesif you know the extent of the subscript values. e.g. Create 3 global variables X1, X2 and X3. You can access them like an array using GetProperty(“X” + index}

1 Like

Thanks, Brent. I thought as much, but I hoped I was wrong.

The array I have in mind will contain something like 125 entries, so it will be not be pretty, but also not impossibly large.

There is zero performance overhead in using a setup like this. If comfortable, the easiest way to set it up would be to create the first GP, Then edit the buildfile, copy that and generate the rest in Excel and paste it back in.

If you put that first GP in a folder, you could export the folder as Xml and later import the spreadsheet output - including folder bits, deleting the old single gp folder afterwards.

Definitely, I keep forgetting about the XML import./export. Much easier.

I’ll definitely try the XML method, thanks!

After the last update of the The Burning Blue module, I promised myself to take a long break before I start a new cycle, but once I have an idea of what should be done, it it is difficult to just put it away. So here we are, and I am glad you have given me ideas for this update that will make the work easier.

It is actually a two-dimensional array that I need, but I intend to make one dimension a simple string. Now I am toying with the idea of editing some pages from the actual rule book into a format that can be imported as XML.It might take me longer than just typing the lot, but it will be more fun!

1 Like

You can simulate an array by using single string with values separated by some character. For example, if you have a property that has integers separated by comma: S = “1,6,3,4,56,6” , then, for example, you can access 3rd element by this approach: (S).split(‘,’)[2]

4 Likes

Thanks, Nelud.

The split() method is very useful, and I looked for something like this, but overlooked it. In any case, here all the values were single letters, so I did it with substring().

If you prefer a programmable way of manipulating the VASSAL module using Python, you could also look into pywargame (shameless self-plug :smile: ). The module allows you to open a VASSAL module, import the Build file and through a Python API manipulate all sorts of aspects in the module. The benefit is that you can encode various relations programmable in a language that is better suited for that then XML and VASSAL’s BeanShell.

Yours,
Christian

The short answer is NO. The long answer has been addressed. A lengthy workaround for a situation that cries out for a better solution - as in - the use of arrays.

Yes, but at least the solution with lots of global variables work. I have now 115 variables, and I have typed slightly more than half.

The XML format is wonderful, because it also allows for much faster identification of spelling errors, and the XML editor I use checks for syntax errors.

I tried this with the Beanshell {(ModuleVersion).split(‘.’)[1]} but I just get expression evaluation errors, am I doing something wrong ?

First of all it’s a particular case with dot delimiter. See here: regex - Java string split with "." (dot) - Stack Overflow
Secondly it seems that ModuleVersion is represened by not a String, so split doesn’t work with it.
I ended up with this working code:

(ModuleVersion).toString().split("\\.")[1]

FWIW, I tried to use the split() method in my module also but got expression evaluation errors. Although I was using commas as decimeters, I tried using the double backslash escape workaround anyway, but no joy. I gave up on that method and ended up padding elements in the string list to be of equal length so that I could reference them using the substring() method.