#179657 - 2007-08-24 11:20 AM
Re: Golf Code...
[Re: Lonkero]
|
Richard H.
Administrator
   
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
You can't put a UDF or most other functions in the test part.
Yes you can. Not to sure why you think that you cannot - do you have an example?
The tricky thing about IIf() is that BOTH the True/False sections are ALWAYS evaluated so you need to be very careful what you put there.
Here is a very simple example that illustrates a working scenario:
$Var1=10
$Var2=5
$Action="Divide"
"Result of "+$Var1+" "+$Action+" "+$Var2+" is "+Iif($Action="Multiply",doMult($Var1,$Var2),doDiv($Var1,$Var2))+@CRLF
$Action="Multiply"
"Result of "+$Var1+" "+$Action+" "+$Var2+" is "+Iif($Action="Multiply",doMult($Var1,$Var2),doDiv($Var1,$Var2))+@CRLF
Function doMult($a,$b)
$doMult=$a*$b
EndFunction
Function doDiv($a,$b)
$doDiv=$a/$b
EndFunction
This works as you'd expect as even though both doMult() and doDiv() are called, the unused return value is simply discarded. This is dangerous though, as (in most languages) if $Var2 was zero you would get a "divide by zero" error even if the action was "Multiply". KiXtart is a bit more forgiving so you don't see the error.
Here is an example of when using functions causes an unexpected side effect:
If 6=IIF($sType="New"
,MessageBox("Thing does not exist - do you want to add it?","Add Item",4)
,MessageBox("Thing already exists - do you want to change it?","Change Item",4)
)
"Ok, Thing is being actioned"+@CRLF
Else
"Ok, you chose not to update Thing"+@CRLF
EndIf
If you run this then *both* MessageBox()'s will appear, though only the return value from the "Change Item" box will be used.
|
|
Top
|
|
|
|
#179667 - 2007-08-24 01:42 PM
Re: Golf Code...
[Re: Witto]
|
Richard H.
Administrator
   
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
You misunderstand, but maybe I didn't explain it very well 
IIF only returns values. However, the values may be derived from any source including complex expressions, the return values of functions, object methods and so-on.
The problem is the way that the parser / runtime resolves the symbols. Basically the expressions in the IIF() statement are resolved to simple values *before* the conditional part is evaluated.
Take one of the examples:
$Var1=10
$Var2=2
$Action="Multiply"
"Result of "+$Var1+" "+$Action+" "+$Var2+" is "+Iif($Action="Multiply",doMult($Var1,$Var2),doDiv($Var1,$Var2))+@CRLF
The IIf() will resolve something like this:
- Iif($Action="Multiply",doMult($Var1,$Var2),doDiv($Var1,$Var2))
- Iif("Multiply"="Multiply",doMult(10,2),doDiv(10,2))
- Iif("Multiply"="Multiply",20,5)
- Iif(1,20,5)
- 20
That's not necessarily the exact process, but it's close enough to see what the problem is. What is clear is that the evaluation of the conditional part is the last thing that happens.
This causes two problems. First, both the true and false expressions have been evaluated - in this case both functions have been called. Second, it means that you cannot use *any* expression which might be invalid even if it is not going to be used. This includes simple variables as well as more complex expressions.
Here is a good example of how easy it is to fall into the trap. Let's say that you want to assign a default when a value has not been passed on the command line:
$=SetOption("Explicit","ON")
$=IIf(IsDeclared($SERVER),$SERVER,".")
This looks fine - if the user has passed "$SERVER" on the command line then it is used. If the user has not specified $SERVER then the local computer "." is used instead.
The problem is that $SERVER is evaluated before the conditional, so the script will abort with an "undefined variable" error if the user has not passed the variable on the command line.
IMO IIf() in KiXtart is an accident waiting to happen, and is only really useful for golf. My recommendation is to avoid it in production work.
|
|
Top
|
|
|
|
#179674 - 2007-08-24 02:31 PM
Re: Golf Code...
[Re: Richard H.]
|
Witto
MM club member
   
Registered: 2004-09-29
Posts: 1828
Loc: Belgium
|
$var = "Yes" IIf($var = "Yes", CallYess(), CallNo()) Function CallYess() "Yes" ? $CallYess = "True" EndFunction Function CallNo() "No" ? $CallNo = "False" EndFunction |
OK, I see. AFAIK "If...Then...Else...EndIf" does not have this problem.
|
|
Top
|
|
|
|
Moderator: Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart
|
0 registered
and 657 anonymous users online.
|
|
|