Loading Groovy Classes – unexpected (and very useful)

3.03K viewsScripting
0

Well it was unexpected to me…

If you define classes in a script file they are loaded when the scripting environment is created (i.e. when Q Modeler starts up). You do NOT have to execute the script to load them. All classes defined in any script are available in the scripting console and to other scripts (try creating a new instance of any user-defined class as the first action on starting the scripting console).

There are two immediate consequences:
1. put your class definitions in a separate Action file. Otherwise you will load new versions of a class every time you amend and execute it – doesn’t impact running models, but can very rapidly eat up large amounts of memory if using large scripts with imported libraries while doing iterative development.
2. don’t use duplicate class names in different actions in the same model file (doing this led me to discover some of these characteristics) – only one class definition is available in the scripting environment, and apart from wasting memory space you can get weird type check failures between the different versions (even though they are not visible).

More interesting is that if you define a static property for a class and store the instance reference in it (a simple way to create a singleton instance) that instance will be available within the scripting environment to [b:1xkvfv03]all [/b:1xkvfv03]scripts.
[code:1xkvfv03]Class Foo {
public static Foo instance
private static int stayAlive = 0
Foo() {
instance = this
...
foo-property = ‘bar’
}[/code:1xkvfv03]
Once you do [font=Courier New:1xkvfv03]new Foo()[/font:1xkvfv03] – anywhere – you can then access [font=Courier New:1xkvfv03]Foo.instance.foo-property[/font:1xkvfv03] from any script. So it is possible to have one script which does some expensive set up, creates some internal data structures, and then access that data from another script (e.g. to find data associated with some selected item). And it’s worth being diligent in providing type references for properties and methods – Groovy doesn’t need them, but it makes the auto-complete functionality in the scripting environment much clearer.

There is one extra wrinkle – you need some other static property to keep the class from being garbage collected – hence the stayAlive property. And another consequence – be very careful using static properties – you can get large memory leaks very easily (noted from experience…) – which is good Java practice in any event.