Coyote's Guide to IDL Programming

Accessing Main-Level IDL Variables

QUESTION: Given the name of an IDL main-level variable, is it possible to access that variable's content from within an IDL procedure or function?

ANSWER: The official IDL position on this subject, prior to IDL 6.1 is that no, this is not possible for a person writing straight IDL code. There is, however, an internal C function, named IDL_GetVarAddr(), that is built into IDL and whose purpose is to do exactly this. It would probably be possible to write your own C program with the functionality you need and add it to IDL as a DLM. You can find additional information about this topic in the IDL External Development Guide. See the chapter named "Variables" for additional information on IDL_GetVarAddr().

And, as it happens, there is a completely undocumented routine name Routine_Names that can do the job. RSI includes Routine_Names in the obsolete subdirectory, but many of their own routines appear to use it. So the general conclusion is that it will not be disappearing anytime soon. But, as always, you use undocumented routines completely at your own risk. There is not much sympathy from anyone when the next version of IDL breaks all your programs.

Craig Markwardt has written a documentation header for Routine_Names from information he and others on the IDL newsgroup (comp.lang.idl-pvwave) have discovered about the program. You can find it on his web page, under the Introspection heading.

If you are using IDL 6.1 and above, IDL now gives you official approval to access and set variables from any IDL procedure or function at any other interpreter level, including at the main IDL level ($MAIN$). The main level is also known as the IDL command line level. Four commands are provided to allow you access. These are Scope_Traceback, Scope_Level, Scope_VarName, and Scope_VarFetch. Consider the following test program.

   PRO TestScope, arg

      ; If argument is passed, set the value of this argument to RED.
      IF N_Elements(arg) NE 0 THEN BEGIN
   
         aColor = Scope_VarFetch(Scope_VarName(arg, LEVEL=1), LEVEL=1)
         Print, 'Current color of argument: ', aColor
         Print, 'Setting color to RED...'
         (Scope_VarFetch(Scope_VarName(arg, LEVEL=1), LEVEL=1)) = 'RED'
      
      ENDIF ELSE BEGIN
   
         ; If argument is not passed, set the value of a variable named "theColor" to AQUA.
         Print, 'Setting the variable "theColor" to AQUA...'
         (Scope_VarFetch('thecolor', LEVEL=1, /ENTER)) = 'AQUA'
      
      ENDELSE
   
   END

Start an IDL session, and try these commands.

   IDL> .COMPILE testscope
   Compiled module: TESTSCOPE.

   IDL> aColor = 'blue'
   IDL> TestScope, aColor
       Current color of argument: blue
       Setting color to RED...
   IDL> Print, acolor
       RED

   IDL> Help, theColor
       THECOLOR        UNDEFINED = <Undefined>
   IDL> TestScope
       Setting the variable "theColor" to AQUA...
   IDL> Help, theColor
       THECOLOR        STRING    = 'AQUA'

   IDL> TestScope, theColor
       Current color of argument: 'AQUA
       Setting color to RED...
   IDL> Print, theColor
       RED

[Return to IDL Programming Tips]