Can’t make SMSForder into type reference

For quite some time I have used SMSForder.
The top of my script includes:

use framework “Foundation” --for ASObjC
use BridgePlus : script “BridgePlus” version “1.3.4”
use script “RegexAndStuffLib” version “1.0.6”
load framework --to use SMSForder methods
property SMSForder : a reference to current application’s SMSForder --standard shorthand procedure in Script Debugger to refer to a class

This works great in Script Debugger, and it has worked in FastScripts, up until:
Today I made changes to the script, but I had to restart FastScripts, and all of a sudden I get this error message when the script is run under FastScripts? But it works when run directly in SD!

Script Error:
Error Number: -1700

Can’t make SMSForder into type reference.

Why did restarting FastScripts destroy the possibility to make a reference to SMSForder?
What do I do now?

What changes did you make ? Can you include the contents of your script so it’s possible to see where and how the SMSForder class is being referenced ?

I already included the relevant lines from the top of the script, except the first two lines that read:

use AppleScript version “2.5” --El Capitan (10.11) or later
use scripting additions --must be here if there is any other ‘use’ statement

The script stumbles right on the line “property SMSForder : a reference to current application’s SMSForder”.

Even the following miniature do-nothing script failed under FastScripts:

use AppleScript version “2.5” --El Capitan (10.11) or later
use scripting additions --must be here if there is any other ‘use’ statement
use framework “Foundation” --for ASObjC
use BridgePlus : script “BridgePlus” version “1.3.4”
use script “RegexAndStuffLib” version “1.0.6”
load framework --to use SMSForder methods.
property SMSForder : a reference to current application’s SMSForder --standard shorthand procedure in Script Debugger to refer to a class
return

But I found a “solution”, though not very trustworthy:
If I remove version “2.5” from the first line, i.e the first line now only reads:

use AppleScript

then restart FastScripts, it works! So one would conclude that one may not specify version “2.5”.

But the super-strange thing is that if I now reintroduce *version “2.5” in the use AppleScript statement, restart FastScripts, it still works! And my original full script also works!

Then I re-did the above procedure a few times, i.e remove and add version “2.5”, restart FastScripts, it sometime works, sometimes not!!?

So what is going on? A strange combination of compilation error and strange caching?

I start to highly question whether it really is a good idea to specify version after any of the statements: use AppleScript, use BridgePlus, use script “RegexAndStuffLib”?

Ideas?

I wouldn’t bother. In fact, you can do away with the use AppleScript line completely. It’s not needed, and the only corollary to omitting it arises if you execute a script using a version of AppleScript that predates the version in which the script was written iff that script contains terminology or makes calls to commands that were only introduced in a version of AppleScript that came after the one attempting execution.

The current (latest) version of AppleScript is 2.8, and so shouldn’t lead to problems of the nature i just described. If you are running on an earlier version of macOS witb an earlier version of AppleScript, were there ever to be any unrecognised commands or terminology used, it’ll either just fail to compile or, by sheer fluke, might possibly compile, which will only lead to the script throwing an error during runtime.

If I were to try and quantify the actual value a use AppleScript line adds to a script, I would estimate it to be close to, or exactly, 0.0.

As to the sporadic nature of your problem, it sounds like the problem is with FastScripts. Therefore, I strongly recommend submitting a bug report via their (his) website, which will, firstly, lead to the confirmation or ruling-out of FsatScripts as the culprit; and, secondly, if it is the source of the problem, allow the creator to be made aware of it and release a fix.

However, to cover a few more bases, you can do a little further debugging. If this were me, I’d be keen to comment out the SMSForder property declaration and see whether FastScripts executes the remaining lines without complaint. If possible, see if you can take steps similar to the ones you described that leads to the referencing error arising, but in the absence of the SMSForder property declaration (so, for the time-being at least, you can keep the use AppleScript version "2.5" line, amending as necessary to try and generate the error). Since it appears at present that the error-throwing line is the one that would no longer be present, we’ll be expecting the barebones script to run error-free.

That being the case, then I’d want to see whether the SMSForder class can be referenced safely at runtime without causing any problems. So, with the declaration for property SMSForder : ... still omitted (or commented out) from the script, you can add this line to the end of the script:

return the current application's SMSForder's frameworkVersion() as text

which should return "1.3.4" (I’m assuming).

On a minor note, you should move the load framework command down a couple of lines so it sits beneath your property declarations. Mostly, this is for neatness, but it’s a good idea to be disciplined in how you layout and structure your code, which includes the order in which groups of related commands appear. It will aid readability, which in turn makes debugging easier, and it will surprisingly help reduce the likelihood of error-prone code. There’s also one or two specific situations where the ordering of AppleScript code makes a big difference in how the script is executed, namely with respect to any top-level declaration that ends up being evaluated (even partially) at compile-time, as these will each affect any other similar top-level declarations that make reference to one another.

The reason this crossed my mind is because the load framework command returns a reference to the SMSForder class instance, which did give me pause to think about any effect this would convey having the property declaration for the SMSForder class reference appear on the line directly under it. But the answer is that it wouldn’t convey any effect, since load framework is a command call, hence the call isn’t going to be made until runtime. Nonetheless, having these lines appear in an order that doesn’t reflect the order in which they are processed by the script is a little disorienting, which is why I would typically move the load framework command down so it is beneath all the property declarations and lexicographically associated with the other parts the script that together would form the implicit run handler.

It follows that having a specific property declaration for SMSForder is somewhat redundant, as your header could easily be reduced a smidge to this:

use framework “Foundation”
use scripting additions 
use BridgePlus : script “BridgePlus” 
use script “RegexAndStuffLib”

set SMSForder to load framework

I suspect doing this would also circumvent whatever issue FastScripts is having (which you should still report to the developer).

It’s actually used by Script Debugger’s code-completion code to filter out ASObjC terminology that’s only available in versions later than that signified by the version number. Crude, but certainly significantly greater than 0.

Don’t do that. The class only exists after the framework is loaded. Because frameworks remain loaded, it can appear to work, but it’s not a good idea.

So what IS a good idea?
(I didn’t invent that line by myself out of nowhere, so I think you wrote that construction somewhere sometime, or it’s in the documentation for SD. After all, my comment says “standard shorthand procedure…” so some “authority” must have suggested it.)

Since the line “property SMSForder : a reference to current application’s SMSForder” comes after the load framework command, shouldn’t that be ok then?

CJK suggested to do it all in one succinct line:

set SMSForder to load framework

Is that a good idea?

It’s better to just use current application's SMSForder in your code rather than a property.

It’s a great approach for system frameworks, where the use framework line loads the framework. But you don’t have a use framework line for the BridgePlus framework (it’s in the library), hence the need for a different approach.

One of things I recommended to @harald was to use the return value from load framework at runtime and assign that to a variable, i.e.

set SMSForder to load framework

As I’ve not got any personal experience with the BridgePlus framework, what’s your view on doing this ? Does that command return an appropriate class reference that can be used in place of current application's SMSForder ?

That’ll be fine. The relevant code in the library is:

use AppleScript version "2.3.1"
use framework "Foundation"
use framework "BridgePlus"

[...]
on load framework
	-- nothing to be done; the framework will have been loaded if necessary
	return current application's SMSForder
end load framework