Home > Tech Geek > Understanding “SCOPE” for beginning programmers.

Understanding “SCOPE” for beginning programmers.

Scope is a term used to describe where a particular asset, be it a variable, object, array or function is available to be accessed. It’s an important concept that needs to be grasped to avoid bugs and reduce the amount of time you spend developing code.

Since the primary audience for this will be posting to the Corona SDK forums, we will be using the language “Lua” in our examples, but this holds true for almost every programming language in use today. Also, since scoping applies to different bits of your program, variables, objects, etc. We will be using the term variable in our code for simplicity, just keep in mind that all the above assets, even functions at the end of the day are variables.

There are a few key terms that we will be using:

  • Global – A global variable is available everywhere.
  • Local – A local variable only exists within the block or chunk of code where it’s defined.
  • Block – A generic term for a block of code. In Lua, these are sometimes referred to as chunks.
  • Namespace –namespace is a term applied to the area where a given variable’s name is active or in context.

Lets talk about blocks for a moment. When it comes to locality, the following programming constructs define blocks:

The file/module containing the code. Thus in lua, your “main.lua” file is one block. Any thing defined in that file is accessible to that file.

In this example, our entire main.lua file is one block. It contains a function, which itself is a block. The variables, characters, location and thisCharacter along with the function pickCharacter are available to be accessed anywhere within main.lua.

Inside the function pickCharacter, I was able to see, access and modify the variable “characters” because it was defined within the main.lua chunk above me.

Functions though are also blocks. Variables created within functions are only available to that function. Lets expand our example:

I made a very subtitle change to the pickCharacter function. I’ve declared a variable inside it called “choice” and I’ve assigned it the value of the random character chosen. I then return the value of that variable to the caller.

The difference here is now “choice” is defined within the block “pickCharacter” so it only exists or is available to that block of code. From my main.lua chunk, if I try to print the value of choice, I will get “nil” because that variable has not been created and initialized within my main.lua block, but within the pickCharacter function block.

Other things that are considered blocks with regards to scope include “IF” statements, “SWITCH” statements (Lua doesn’t support switches, but many other languages do) and your looping statements, “WHILE”, “REPEAT”, “FOR”, “FOREACH”, etc. Again Lua doesn’t support all of these, but you will run into them in other languages.

Not all languages let you declare variables inside these blocks either. For instance in ‘C’, your variables all have to be declared at the top of a function block, yet in ‘C++’, you can define them in the middle of a FOR loop.

Declaring Variables

In a language like C or Objective C, you have to be very explicit with your variable declarations:

If you do not declare a variable at the top of the function or in a valid place in C++/Objective C, the complier will give you an error and not build your program. When languages like JavaScript (which lead to Flash’s ActionScript) and PHP were developed (and Lua has this same behavior) variables no longer had a specific type and no longer had to be declared. You could just start using a variable:

I no longer had to tell the system if it was a string, number, table etc. I could just assign values and go on. An “optional” “var” tag is allowed.

This is where paying attention to scope becomes critical. The “var” isn’t optional. It controls the scope of the variable. In Lua, this is the same as putting the word “local” before a variable. What is the difference?

In Javascript and Lua if you DO NOT put the var or local in front of the variable the first time you reference it, it becomes a “Global Variable”. It is accessible anywhere with in your program. Cool, that means I don’t have to worry about passing my variables around or worrying about scope, I can just make everything global…..

Not so fast, there young padwan learner. Globals are very bad things if you treat theme without caution and careful regard.

Lets look at an example using the infamous “I” index variable:

The variable I changed from 10 to 12. Why? Well lets look at the code for the function myFunction:

The developer of myFunction didn’t localize the variable I (nor the variable count for that matter) and when myFunction runs, “I” is left at 12 when the for loop ends so you in your program expects “i” to still be 10, but its not because both your “i” and the function’s “i” are accessing the exact same variable. If you used a variable called count, it would get trashed too by the function.

Therefore it’s important that when you write functions that someone else may call later (if your working on a team) or for your own sanity, to make sure you localize variables and just not use globals because they are easy.

This problem would be solved by the function being written as:

Specifically within Lua when using modules, global variables are available to all modules. Lets say I have a variable I define in main.lua as:

and I’m in another module, say “level1.lua” and I print the value of “score”, I will get “100” printed. Lua supports a special table called _G which you can add member elements too for this purpose of passing around variables between modules. But don’t over use it. And its good to use _G instead of loose variables like the “score” example above since its visually intentional that you intended for that value to be globally available instead of just sloppy code.

Lua does you a favor and namespaces your variables for you behind the scenes. Lets look at this example:

You will get the following output:

Within the scope of myFunction, “count” is a unique variable to that block of code. When it returns, my original “count” variable remains untouched. This is an important concept to understand if you are unsure of when to use the word “local” in front of a variable or not. Lets look at the same example without the word “local” in the function:

You will get the following output:

In this case, we didn’t localize “count” to the function, so when it looked to find the variable “count”, it went up to the next higher level and found a variable within that chunk’s scope which is available to my function and the higher level “count” variable changed.

Of course avoiding using the same name variable in different places helps avoid these problems, but in languages like Lua were we can use untyped, undeclared variables, it’s critical to understand when variables are in scope and when they are not.

Hopefully this will help you understand the “local” tag and when you need to use it and help you avoid unnecessary headaches. Happy Coding!

Categories: Tech Geek Tags:
  1. October 15th, 2011 at 06:13 | #1

    Hi,

    Very good post! Thank you for the beginner`s effort as I said you in the Corona Forum. ;)

    It helps a lot understanding some “WHYs” of the code running.

    Regards,
    Rodrigo.

  2. Ilhee Kim
    December 17th, 2012 at 03:33 | #2

    Your post has error.
    in for loop initial variable “i” has for loop scope.
    So,
    for i = 1, 10 do
    print(i) — print 1~10
    end
    print (i) — print nil

  3. Paul Peterson
    April 4th, 2013 at 21:47 | #3

    Old time procedural programmer here. I’m still not sold on the use of scope / local variables. I say just always use globals! The last example is a good one. When I scan down code quickly, I don’t want to see the same variable name in different locations and have to figure out if it’s the local or the global one being referenced. Simply use more unique names when using all globals; like countBalls, countDelayLoop, etc. Did the designers of OO/scope forget the KISS principle ??

  4. April 4th, 2013 at 22:54 | #4

    Lua performance issues aside, in a single file/module program, it’s not a problem, but lets say you want to use someone else’s module and you both device to use coundDelayLoop. The variables will stomp on each other. Yes, you can name space all your variables, but then you have 2 – 3rd party modules and they are stomping on each other. This really isn’t an OOP concept. Any language from Pascal to C had you declare variables at the top of each function that were of sole use to that function. C++ did bring in the concept of having variables defined at any block level.

  1. January 30th, 2013 at 13:04 | #1
  2. February 22nd, 2013 at 14:51 | #2

%d bloggers like this: