LiveCode Journal - LiveCode Tutorials

Everything You Know Is Wrong, Part 1

by Mark Wieder, Ah Software

I've always distrusted "it" and "the result" as being too ephemeral to use without having them changed out from under me by who-knows-what. Now after some experimenting and some email conversations with Mark Waddingham [lead engineer for RunRev Ltd], I think I've finally gotten things sorted out.

First off, I always thought that one of the main differences between functions and command handlers was that functions would return values. For instance,

-- make an entire string uppercase
function Ucase1 pString
  local x
  repeat with x=1 to the number of chars in pString
    put upper(char x of pString) into char x of pString
  end repeat
  return pString
end Ucase1
-- vs
-- put the uppercased string into a field
on Ucase2 pString
  put ucase(pString) into field "someField"
end Ucase2

Well, it turns out that command handlers can return values, too.

-- put the uppercased string into a field
on Ucase3 pString
  put ucase(pString) into field "someField"
  return "done"
end Ucase3

in which case the string "done" ends up in the "result" variable.

Note that XFCNs and XCMDs in external libraries can also set the value of the "result" by returning a string in the proper argument. In the case of XFCNs this value will also be placed into the "it" variable. Note also that this is different from setting a boolean value in the r_error argument, in which case a False boolean will cause the calling script to halt with a script error.

So where does this leave "it" and "the result"? The "result" variable is set on return from either a command or function handler. In the first case, Ucase("hello") will leave "HELLO" in the result. In our second example the result will be empty. In our third case the result will contain "done". In each case the result variable will be changed.The "it" variable is not changed by any of these calls. However, the calling syntax for commands and handlers is different.

While you can call a command by issuing just its name, you have to call a function differently. The arguments are enclosed in parentheses and something must catch the expected return value. Programmers used to other languages will recognize this as an rValue.

Ucase2 "hello" -- command
get Ucase1("hello") -- function
put "the uppercase answer is" && Ucase(something) -- function

The "put <expression>" syntax will use whatever is in the "result" variable at the end of evaluating <expression>. The "get <expression>" command is a shorthand way of saying "put <expression> into the 'it' variable" (as well as the 'result' variable). Therefore, something like

on mouseUp
  get SetIt() -- changes both "result" and "it"
  MyHandler -- only affects "result"
  put the result into field "testresult"
  put it into field "testit"
end mouseUp
on MyHandler
  return "hello"
end MyHandler
function SetIt
  return "bucko"
end SetIt

This puts "hello" into field "testresult" and "bucko" into field "testit", so my conclusion here is:

1. functions set both "it" and "result" by reason of their calling syntax.
2. commands can set the "result" by returning a value.
3. the main difference between commands and functions is the calling syntax.

There are only a few exceptions to this handling of the "it" variable. The url syntax in particular is documented as affecting "it". See the documentation of the "put" command for a thorough examination of this topic.

© 2010 Fourth World Media Corporation All rights reserved. Portions copyright by the original authors.