!NULL to throw away a function result
Occasionally, you may want to use a function to make use of input-output parameters, but you may not care about the result. A good example is with the WHERE function:
result = WHERE(arr EQ 1, count)
In this expression, perhaps you don’t care about the actual position of the value 1, but instead you just want to know whether or not the value 1 is contained in the array; therefore, you will use the count but will never use the variable result again. Rather than carry this variable around, it can simply be thrown away by using !NULL, and IDL will never store it:
!NULL = WHERE(arr EQ 1, count)
This can also be used with the TEMPORARY function to dispose of an existing variable:
var = 1
!NULL = TEMPORARY(var)
help, var
VAR UNDEFINED = <Undefined>
Not only is this useful for freeing memory, especially if the variable is very memory-intensive, this also helps debugging by temporarily capturing results from multiple functions in order to break expressions into multiple lines. For instance, the following line is difficult to debug because IDL will only step into one function; stepping out of the first function will return to the next line, and IDL will not step into the second function.
IF func1(var) && func2(var) THEN BEGIN
...
ENDIF
…and the following line has the same problem:
IF func1(func2(var)) THEN BEGIN
...
ENDIF
Instead, you can create a couple of temporary variables:
temp1 = func1(var)
temp2 = func2(var)
IF temp1 && temp2 THEN BEGIN
...
ENDIF
!NULL = TEMPORARY(temp1) & !NULL =TEMPORARY(temp2)
…and
temp1 = func2(var)
temp2 = func1(temp1)
IF temp2 THEN BEGIN
...
ENDIF
!NULL = TEMPORARY(temp1) & !NULL =TEMPORARY(temp2)
(Note that this is similar to DELVAR, but DELVAR is only a main-level routine and cannot be used within a routine).
Use RETURN or CONTINUE in place of an IF block
Sometimes code can be simplified by immediately leaving the current section of code rather than using a large conditional statement. Here are a couple of examples.
If the conditional statement is at the end of aroutine, like this
PRO myroutine
...
IF(condition) THEN BEGIN
...
ENDIF
END
you can simply return out of the procedure once the condition is determined to be untrue:
PRO myroutine
...
IF(~condition) THEN RETURN
...
END
Similarly, CONTINUE can eliminate conditional blocks in loops:
FOR i=0,10 DO BEGIN
IF(condition) THEN BEGIN
....
ENDIF
ENDFOR
Instead:
FOR i=0,10 DO BEGIN
IF(~condition) THEN CONTINUE
...
ENDFOR
Use SWITCH instead of multiple OR checks
Sometimes you may have a statement like this:
IF var EQ 1 || var EQ 5 || var EQ 8 || var EQ 11 THEN BEGIN
...
ENDIF ELSE IF var EQ 12 || var EQ 13 THEN BEGIN
...
ENDIF ELSE BEGIN
...
ENDELSE
Making use of SWITCH can avoid typing "var EQ" multiple times:
SWITCH var OF
1:
5:
8:
11: BEGIN
...
BREAK
END
12:
13: BEGIN
...
BREAK
END
ELSE: BEGIN
...
END
ENDSWITCH
Additional IDL tips
Additional tips for efficient programming can be found here:
Tips & Tricks for Efficient IDL Programming