special handling for CreateArray() arrays and global variables.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

special handling for CreateArray() arrays and global variables.

Bob Zawalich

ManuScript programming: special handling for arrays (not Sparse Arrays) and global variables.


One of the first important things I learned about programming in ManuScript is that arrays and global variables are evaluated as pointers (or addresses), rather than as strings or numbers. This often creates problems.


There is one good use for this, which is that it allows you to create arrays of arrays, but in general it is an endless source of bugs. I note that sparse arrays do not do this: if you have a string in a sparse array and say


str =  arsSparseArrayTemp[i];


str will just be a string, or whatever object the sparse array is holding.


Using arrays (as created with CreateArray())


If you want to assign the contents of an array entry to a variable you must force the array entry to be converted to a variable of the desired type.


If it is a string, then always say str = “” & arr[i];

If it is a number, then always say num = 0 + arr[i];


If you do not do this, your program will not work correctly.


The one time you do not do this is it you are copying an entire array to another array. For an array used as a dialog list box filler that I cannot initialize before runtime, I typically define a global variable, such as dlg_lstTextStyles in the Data area. Then at runtime, I will fill the list by creating a local array,


arr = CreateArray();


then fill the array with strings as needed, then assign the local array to the global variable


dlg_lstTextStyles = arr;


Note that I am not using “”& or =0+ in this case. The pointer to the array is being transferred, not the contents of an entry.


In all other cases it is best to do something like


str = “” & arr[i];

if (str = “Why does this not work?”)


rather than


if (arr[i] = “Why does this not work?”).


Beware also of passing arr[i] as a parameter to a method, or passing a global variable as a parameter. Sometimes it works and sometimes it doesn’t, and when it doesn’t you spend a lot of time trying to figure out why. I find it avoids hours of difficult debugging to just always force array references to be strings or numbers.


One other quirk of arrays: Do not store Booleans values (True/False) in an array. You can store a string or number instead, which will work. I always store 1 for True and 0 for False, and have the method TrueFalseAsNumber to make the conversions easier.


            TrueFalseAsNumber "(flag) {

// arrays do not like the values True and False.

// For True substitute 1, and 0 for False


if (flag)


            return 1;


return 0;}"


Global variables


Global variables are defined in the Data area of the plugin editor. They can be strings, numbers, or arrays, and they retain changed values within a Sibelius session, and their values are stored in the plugin text file.


You can create global Sparse Arrays and Dictionaries, but these use a different mechanism. Their values are not stored in the text file, and their values are lost when a plugin stops.


Global variables are required for variables in dialogs and if you have methods invoked by dialog controls they are often needed because such method will not have any parameters passed to them. So you really can’t avoid them.


Here is what a global string, number, and array look like in a plugin test file:


            g_string "I am a string"


            g_number "3.14"







String and number are literal strings, with the value, if any, enclosed in double quotes. Arrays are literal strings enclosed in brackets {}


You can use an initialized global array directly


for i = 0 to g_array.NumChildren


            trace (“” & g_array[i]);



Always force global strings or numbers or array entries to be strings or numbers before use:


str = “” & g_string;

num = 0 + g_number;

str = “” & g_array[i];


You can sometimes get away with not doing this; for example trace() seems to be able to deal with unconverted arrays and globals most of the time. But when these kinds of things go wrong it is very hard to find them (especially if you have not using naming conventions to indicate that a variable is a global). So I strongly recommend following these as strict rules whenever you can. It will save a lot of heartache at debugging time.





Plugin-dev mailing list
[hidden email]