Variable Scope

Variable scope is an important part of any successful programming language. The idea is that every function runs in it's own separate "scope", i.e. it has no way to access or know about variables outside of those it specifically creates. In other words, functions are separated from eachother. The most important consequence of variable scope is that every function you run can use the exact same variable names as every other function, and there will be no confusion between the functions. An example is best. Below is a simple procedure and some code to run with it:

pro test_procedure
testvariable = 20
print,testvariable
end

testvariable = 50
print,testvariable
test_procedure
print,testvariable
; prints 50, 20, and then 50

In IDL the command line defaults to the "main" level when you first launch IDL. Any variables created at the main level will always be available as long as you are at the main level (yes, that's a rather obvious point, but worth mentioning for reasons that will become apparent shortly). Anytime you run a function from the command line, a new level of scope is created below this main level, and the function runs in this new scope. This is where things get a little tricky. Although at first the command line is at the main level, it doesn't always stay there. By default in IDL when a function or procedure encounters an error function execution will hault, you will return to the command line, but the command line will now be in the scope of the function that encountered the error - not in the main level. This is done to give you the ability to examine the state of your function and find bugs, but it can be extremely irritating if you don't understand what is going on. Since you are not at the main level, you don't have access to any variables you might have created before your function execution started. Here's an example program to create, and then a series of idl commands to run to illustrate this behavior:

pro test_procedure
testvariable = 30
print,non_existent_variable ; this will create an error
end

a_variable = 'hello!'
test_procedure
print,a_variable
print,testvariable

IDL says:

% PRINT: Variable is undefined: NON_EXISTENT_VARIABLE.
% Execution halted at: TEST_PROCEDURE 3 /astro/homes/cmancone/idl/test.pro
%
% PRINT: Variable is undefined: A_VARIABLE.
% Execution halted at: TEST_PROCEDURE 3 /astro/homes/cmancone/idl/test.pro
%                      $MAIN$
      30

To reiterate: test_procedure is called, an error is encountered, and the user is returned to the command line. At this point the user attempts to print out their previously declared variable, 'a_variable', but because IDL is still in the function scope this main-level variable can't be found, and another error is returned. On the bright side, because IDL is still in the function scope, it is possible to print out variables inside the function itself, such as testvariable. This fact is very useful for debugging purposes.

The moral of the story is that if you do have an error in a function (and you will) you will want to debug your function as much as possible and then return to the main level right away so that you can access all your data again. IDL has provided a very simple way to do this: the 'retall' command. After a procedure encounters an error the retall command will return you to the main level. Of course once you type retall and are returned to the main level, you no longer have access to the variables that existed in your function.

a_variable = 'hello!'
test_procedure
retall
print,a_variable
; prints hello!
print,testvariable
% PRINT: Variable is undefined: TESTVARIABLE.
% Execution halted at: $MAIN$