Code Detectives and The Case of "Leaky Scope"
When not properly defined and isolated, the scope of your programming variables can lead to numerous and nefarious crimes in the final application—and subsequently the end user experience. Therefore, the scope of each variable is something to be protected. Variables that are not properly protected lead to a programming problem called “leaky scope.”
Our typical touchscreen interactive project will include at least 100 variables for animations, gesture controls, dynamic data and navigation options. It’s easy to let the scope of any individual variable get mangled up in a mysterious mess that would confound the combined wits of Encyclopedia Brown and Nancy Drew.
Keep in mind, even a tangled web of variables may compile and run…at first. However, when variable scopes get interweaved, you may be in for a long night of playing “who done it.” The process of reviewing of your code, updating your application, debugging, and subsequently fixing your application becomes much more difficult than playing Clue without any room cards.
Certainly, when designing a program we need to be interested in how the computer reads our code, but we also need to be concerned with the level of difficulty other humans (as well as our future self) will have in deciphering our work. Different types of leaky variable scope have different levels of impact on our final program.
Your mantra should be “do only what is absolutely necessary.”
In this post, we’ll review a few common examples of leaky scope that we often find in third-party components. These examples have easy fixes that can improve the readability of code and make it harder to introduce mistakes.
The first leaky scope we always want to eliminate is the “loop iteration variable.” For these samples, the intent is to “DoSomethingCool” with variable “i” anytime “i” is less than 30.
When comparing this code, we have to ask:
• Is the variable supposed to have another responsibility other than iteration at hand?
• If not, is this variable being given some other responsibility, perhaps by accident?
• Will any future code be tempted to use this out of scope variable?
The simple solution is to confine this variable to the “for” loop. This restriction in Sample 2 will innately declare its bounds. We want single variable responsibility right? So, if the variable’s sole purpose is to be a means of navigating a loop, then its whole lifecycle should be kept within that loop. In general, you should prefer “foreach” to “for” loops whenever applicable. With a “foreach” loop the iteration variable is scoped and immutable, altogether avoiding the “loop iteration variable” issue.
Another instance where leaky scope can creep in to our program is when we store data in a class variable that could simply be stored as a function variable or passed as a parameter. We frequently encounter this type of leaky scope when parsing event data from third-party data sources used by our museum and library customers.
Here is a code example that forgoes any kind of error checking or best design practices.
Did you catch the problem? If we don’t have to access the data later, then we should not store it. In other words, why introduce more complexity to our class? Your mantra should be “do only what is absolutely necessary.” Keep your class as simple as it can be, or no more complex than it has to be. With these words ingrained in our heart, here is a revised code snippet:
Another benefit of the coding style in Sample 4 is that it allows us to think in a more linear way. In Sample 3 data was a state in our SomeClass instance, calling GetSomething set off a chain of methods, each method then in turn accessed our class state and mutated our class state, not good. In Sample 4 data is not our class state, instead each method works is passed what it is intended to work on and returns its result. This is much easier to reason about, especially when were dealing with something of more complexity.
If you’ve made it this far, let’s try one last example of leaky scope. In the next bit of code, we create leaky variable scope when we use statements where we could use expressions. We should always prefer expressions over statements, because statements force mutations.
For this next sample, let’s imagine that we are creating an interactive exhibit for a detective’s hall of fame. We’ll need to execute code based on which member of the mystery crew you select:
This code immediately ends up in a dark and creepy cemetery. Let’s see if we can do better by putting in the effort to write an expression.
This revised code produces a much more reliable result with a much more stylish line of code.
Whether you’re programming a standalone interactive or downloadable mobile application, we hope these brief examples will help you produce tighter code for your next project. The leaky scope phenomenon is a frequent issue, and it can lead to hours of lost programming productivity. Be mindful of what variables have access to what and why. It’s rather elementary when you favor the strictest level of access possible to save yourself additional rework.