Sorting out behavior of “IF /
ELSE “
The “ELSE” part of an IF statement is assumed in Lisp. So,
if not careful, you may get unexpected behavior.
Here is a recent change (in blue/gray highlight) someone
pushed up to Perforce for one of the lisp files:
(setq x nil)
(setq cnt 0)
(while (<
cnt (length ss))
(if (nth cnt ss)
(setq en (handent (nth cnt ss)))
(if en
(progn
(setq x value1)
(if (not x)
(setq x value2)
)
)
)
)
This looks pretty benign… but it will likely cause a
regression.
To better see this problem, here is the same code with an
“ELSE” comment inserted where end of the “True” part of the IF statement
ends and the assumed “else” part of the if statement begins:
(setq x nil)
(setq cnt 0)
(while (<
cnt (length ss))
(if (nth cnt ss)
(setq en (handent (nth cnt ss)))
;
ELSE
(if en
(progn
(setq x value1)
(if (not x)
(setq x value2)
)
)
)
)
So, here’s what will happen. The IF statement checks (nth
cnt ss) to see if it is non-nil. If it is non-nil, then it fills variable “en”
with the converted handle value in (nth cnt ss). Then it exits the IF
statement. But, if (nth cnt ss) is nil, then a second IF statement checks
undefined / uninitialized variable “en” and, if it happens to be non-nil, tries
to do something with it. Likely it will do something not expected or desired.
Grouping lines of code in an
IF statement
A better way to set up this IF/ELSE statement is probably
something like this:
(setq x nil)
(setq cnt 0)
(while (<
cnt (length ss))
(if (nth cnt ss)
(progn
(setq en
(handent (nth cnt ss)))
(if en
(progn
(setq x value1)
(if (not x)
(setq x value2)
)
)
)
)
)
The beginning “(progn”
and ending “)” to balance it groups all
of the in-between lines of code
to be executed for the “True” part of the IF statement. This is probably
what needs to happen here.
So, two things to watch for which may help avoid creating
new regressions:
1.
Go ahead and show the “; ELSE” comment in an IF
statement when both conditions are being coded up.
2.
Use the “(progn “ flag to group two or more
lines of code together that need to execute for a single condition of the IF
statement