Global variables are not a plot of the Lizard People
Wouldn’t it (well, maybe?) be great if Lizard People (I invite you to read here if you’ve never heard of the term) controlled OneStream Business Rules? Briefly, an imaginary force – apparently from the Draco or maybe the Sirius or perhaps the Orion constellation* — controls the world, thus absolving humans from the responsibility of making it into the less-than-tidy state than it is today. So, kind of great for collective guilt, except for the all the evil bits that Lizard People bring to the table. Actually, no, not at all, but might it be equally great if there was some sort of omnipotent-and-not-at-all-malevolent force that controlled and shared data across Business Rules? There would be. And there is.
Global? Does that mean I need a passport?
As travel broadens the mind, so too do global variables extend the scope of data. Instead of a variable being local to a function or a subroutine or local to a class in a Finance Business Rule (all Finance Business Rules are classes) as a public variable, a global variable is available to all rules. It is – as the name suggests – global to an application.
A use case (there are many) would be to have a single place to derive a value and then share it across more than one Business Rule and run it only once. This is in contrast to a separate class that derives the same value in a single code location but must be instantiated and executed every time its results are required. Both work and are conceptually the same but potentially (and probably) the separate class approach could be more expensive because it executes more than once.
NB — In OneStream there are seven (or eight or eleventy million) ways to attack a problem and solve it. This blog cannot tell you which approach is best; it can only illustrate a potential path. I happen to like this one.
One of the use cases for a global variables are Data Tables (see here and here and here and here and why not here to get a better feel for their use case) whose results are needed in multiple other Business Rules. Run once, use universally. Such is the promise. Or is it?
It’s super easy, really. It’s the using that was for Yr. Obt. Svt. a challenge.
A global variable is a Dictionary. It needs a unique key and a value: a Key Value Pair. A unique key might be “Cameron” or “26September2022” and the value could be a String or a Decimal or even another Dictionary. The value is accessed by referring to the key.
A Global Variable that is a Data Table or is that a Data Table that is a Global?
You’ve seen this before but with a twist:
The only new bits (I am nothing if not lazy when it comes to reusing code and besides this is a good example) are steps 1 and 2 where I create a global data table variable using globals.SetObject with a key of “Global_DataTable” (1) and then prove to myself that I’ve valued that global variable (2). And yes, creating and retrieving a global variable within the same rule is silly – this is just a proof of concept.
Does it work?
And then it doesn’t
We now have a global variable. Hooray, huzzah, & c. Let’s use it globally. To do this I run the Business Rule that values and creates the global variable and then run another Business Rule that gets said global variable and does stuff with it.
What could possibly be easier?
Here’s that second rule:
Executing this rule produces the dreaded:
That object seems to not exist. Bugger.
I can test to see if the global exists and if not, don’t try to access it:
When I run it this time, I don’t get an error, but alas that global isn’t valued:
What’s going on?
When I was first messing about with this, I was confused with “confused” being a stand in phrase for excited then puzzled then curious then frustrated and then finally mad. Code isn’t worth being mad.
I turned to my Younger, Taller, Smarter, and subjectively Better-Looking Brother From a Completely Different Set of Parents, Celvin Kattookaran and asked him why on earth why this wasn’t working. In his calm and measured way he showed me the error of my ways which is humiliatingly simple.
Put it into a Data Management Sequence
The scope of global variables is for the life of the execution of the rules that create them and then consume them. In OneStream, that means that the rules must be run in the same Data Management Sequence. That’s it. OMG, the amount of time I struggled over this. Sad.
My cluelessness aside, this is all that’s required:
Now when I run it:
Let’s prove that it’s really there:
Ta da, redux:
So what? This is what.
Now that you (and, finally, me) know that the trick to using global variables is to encapsulate them in the same Data Management Sequence, as the Bard once said, the world is your oyster. Perform a complex (and likely expensive) procedure once and then share it across as many other rules as required. It’s a fantastic way to centralize and simplify your code. As noted above, it’s not the only way to address this requirement, but’s a pretty geeky cool and performant one.
Be seeing you.
*FoMoCo’s Greatest Hits
I don’t have a picture of it that I can find, but once upon a time I had a 1990 Ford Orion diesel as a company car. If I could have figured out how to bring it back to the States, I would’ve. I loved that car. And when I did a Big Oops and filled it partway with gasoline (sorry, petrol), it just chugged away instead of grenading the engine as it probably should have. Great car. As great as global variables? Quite possibly yes. High praise indeed.