2 of 2 people found this helpful
There is a behavior in FM that the Exit Script result may persist across sub scripts.
Say that you have a script "calling script"
it runs script A and that one exits with result "a"
it then calls script B and that one does not exit with anything
after script B runs you check Get(ScriptResult) and you get "a". That may not be what you intended because B ended without a script result and empty/null/nothing is what expected.
So to overcome that you should explicitly take control over your script results. Which can only be done through the "Exit Script" script step.
Note that you have to make it exit with an explicit result to overcome this behavior. So you could use
Exit Script [ $null ]
Exit Script [ "" ]
Exit Script 
So Get ( ScriptResult ) is essentially unreliable because an intervening script may or may not change its value.
Is there any reason not to just prohibit the use of Get ( ScriptResult )? Wouldn't that be an easier policy to maintain?
1 of 1 people found this helpful
also it helps when using the debugger ... the debugger window stays open so you can see results of the last script step, before the Exit Script
There is another reason to end every script with an Exit Script (or at least a comment line): if you are debugging a sub-script and for any reason you want to skip the final part of it and continue with the calling script, you can move the debugging cursor to that final line and go on from there. If your sub-script does not end with a comment or the Exit step, you must execute its last command in order to exit from it.
Perhaps it helps to distinguish it from Halt Script which terminates scripts and subscripts currently running, whereas Exit Script only terminates the script in which the command is executed. Any other scripts that may have called on that script will continue to run, plus get the added benefit of getting the Get(ScriptResult) mentioned above.
Prohibiting the use of Get ( ScriptResult ) would mean that scripts would have to communicate with each other via less well encapsulated mechanisms, such as global variables and fields, and that will very quickly become more difficult to maintain than it's worth.
I was trying to come up with examples of that being the case. Do any come to mind for you?
I'd phrase it differently. Get ( ScriptResult ) reliably returns the last result that was explicitly passed back to the calling script by a subscript. It's we humans who are unreliable, and may not always remember which subscript did or didn't end with an Exit Script step containing an explicit result. Thus the utility of making it a habit to always end with an explicit step, as Wim replied.
As far as prohibiting passing results back to calling scripts—or, as long as we're going down this path, the logical cognate of prohibiting passing values into subscripts via script parameters?—those two capabilities are two of the most useful additions to the FileMaker toolbox in the past dozen or more years! As jbante pointed out, the alternative in years gone by involved passing values around via global variables* or fields, opening things up to variable-name collisions, possible security holes, etc.
(*Actually, I think global variables and script parameters were introduced about the same time, iirc, so before we had those, global fields mucked up the data schema in order to help pass values into scripts.)
Passing parameters into scripts seems unrelated, because Get ( ScriptParameter ) will only ever return exactly the parameter passed to the very script from which it is called. (Right?)
Otherwise, if it's not a defect in Get ( ScriptResult ) that because it may return the result of one script after executing another script, we have to put an Exit Script [ "" ] at the end of every script, then I suppose I can simply accept all this as a reminder of FileMaker Pro's eccentric nature.
Get ( ScriptParameter ) will only ever return exactly the parameter passed to the very script from which it is called. (Right?)
I believe you meant "will only ever return exactly the parameter passed from the very script (/button/menu command/trigger/etc.) from which it is called."
Your statement is, of course, correct that a script can only be called by one script (at a time) but can call multiple others in the course of its execution (each potentially returning a result). Other than that distinction, script parameters and script results are very much two peas in a pod, which brings us to…
we have to put an Exit Script [ "" ] at the end of every script
Hopefully, johnnyb, you're at least occasionally finding uses for passing an actual result back to a calling script*, and not always just an empty string. If not, you're missing out on a powerful capability. Passing explicit values between blocks of code via parameters and results is a pretty standard programming "best practice," and usually preferable to using the global namespace for that.
(*and you probably are . . . I just wanted to make sure you haven't missed out on the possibility.)
I just ran a test and it seemed get(ScriptResult), like Get(ScriptParameter) is private as well, in this case, private to the script that made the Perform Script call. In other words, if you watch the get(ScriptResult) parameter, it does not get set globally throughout the file until another ExitScript[""] command is executed.
That suggests, actually, something approximating JS return command, though I wouldn't push the analogy too far.
Side note: JS being the meticulous fusspot that it is, a function without an explicit return value returns undefined rather than null. FMP without an explicit ExitScript step will result in a get(ScriptResult) of "" (empty string)
If I call Get ( ScriptParameter ) in a script, then I expect it to give me the value of the parameter passed to that script. Does that help?