Monday, 11 April 2016

Understanding variable scope

In APEX, we have two primarily languages we would tend to work with:

  • PL/SQL
  • JavaScript
So, it's worth being aware of how variable scoping works in any program units you are developing.

If you don't already know it, JavaScript has function level scope, rather than block level scope. If you come from C-based language, and declare a variable inside a for loop, for instance, you would not expect that variable to live on outside of the loop.

This is not the behaviour of JavaScript, so let's give this a test to see:

When the variable i is declared, it is actually hoisted up to the to the top of the function. If you added a statement to the top of the function referencing i, i would have the value of undefined rather than a ReferenceError about using an undeclared variable.

No matter where a variable is declared in JavaScript, it is hoisted to the top of the containing function - something to be aware of. That's why you will often see JavaScript programs with all variables declared at the top of the function - and considered good practice.

If we introduced this into a language such as Java, we would get a compilation error for trying to use an unknown symbol - that is of course because the variable is only available in that particular block.

So, then, how does PL/SQL behave?

Well, for starters, PL/SQL has a bit more structure to it requiring variables to be declared in the declaration block - as opposed to having the ability to declare anywhere throughout the body of the program (aside from loops where the iterator can be declared inline - `for i in 1..100`).

In saying that, you can declare more variables inline by nesting additional blocks, and those nested blocks will naturally inherit properties declared above them. 

The same applies to named sub-units.

If we add a variable to a sub-unit of the same name, then we have a new variable to work with without over-writing the existing variable. 

What may be useful, is that we are able access the variable from the parent program unit by prefixing the name or label of the program unit with dot notation when accessing the variable. Be careful here though, if you have a label with the same name as a named program unit, it will use the closest match.