In InterSystems Caché (when you’re not using procedure blocks), all variables are of global scope — if Function A sets a variable and then calls Function B, Function B can see all the parameters Function A passed it plus any other variables Function A set (or that Function A’s caller set, or that Function A’s caller’s caller set…) Once a Caché global variable (in Caché parlance, the term global has a different meaning, so we refer to these as floaters…) — once a Caché floater has been set, it floats throughout the system, as you’d expect of a global variable.
Mitigating the Floatitude
Having many such variables floating through the system de-modularizes the system and makes it easy for a change in one area of the system to cause unintended side-effects in another area of the system. This effect is somewhat mitigated by Caché’s NEW command.
The NEW command creates a new “stack level” at the point it is invoked such that the global variable appears undefined from that point on, until the end of the block where the NEW appears. If the global variable is set to a different value after NEW has been called, the value persists only while the NEW is in effect, and once processing falls of the end of the block where the NEW command was called, code accessing the global variable will see the value it had before NEW was called.
All this to say, I just read about a function in Perl that looks just like Caché’s NEW command: the
A local() modifies its listed variables to be “local” to the enclosing block…and to any subroutine called from within that block. A local() just gives temporary values to global (meaning package) variables. It does not create a local variable. This is known as dynamic scoping. Lexical scoping is done with “my”, which works more like C’s auto declarations.
…All listed elements must be legal lvalues. This operator works by saving the current values of those variables in its argument list on a hidden stack and restoring them upon exiting the block, subroutine, or eval. This means that called subroutines can also reference the local variable, but not the global one.
And from the top of that section:
NOTE: In general, you should be using “my” instead of “local”, because it’s faster and safer. Exceptions to this include the global punctuation variables, filehandles and formats, and direct manipulation of the Perl symbol table itself. Format variables often use “local” though, as do other variables whose current value must be visible to called subroutines.
This sounds similar to InterSystems’ advice to use procedure blocks when writing new code.
My guess is that people tend not to write enterprise applications in Perl and that because of this the maintainability issue isn’t as pronounced there.