gurkensaas
gurkensaas

Reputation: 913

Is there a way to have constants in Applescript?

I'm currently working on an Applescript math library, which mimics the python math module. The python math module has some constants, such as Euler's number and others. Currently, you can do something like this:

set math to script "Math"

log math's E -- logs (*2.718281828459*)

set math's E to 10

log math's E -- logs (*10*)

So I tried searching for Applescript constants and came across the official documentation, where it is stated, that You cannot define constants in scripts; constants can be defined only by applications and by AppleScript.

Is there a clever workaround for this or would I have to write a .sdef file for this sort of thing?

EDIT:

I have now also tried this:

log pi -- logs (*3.14159265359*)

set pi to 10

log pi -- logs (*10*)

pi is an Applescript constant. If you run the script a second time without compiling again, it looks something like this:

log pi -- logs (*10*)

set pi to 10

log pi -- logs (*10*)

I don't want to mimic this behavior, but more so the behavior of other constants like ask, yes, no, etc. which complain, even if you try to set them to themselves.

Upvotes: 0

Views: 515

Answers (2)

Robert Kniazidis
Robert Kniazidis

Reputation: 1878

Every handler name with parameters is constant in the AppleScript. You can use this fact. Here, you can't change the name of the handler, so you can consider it like your constant pi identifier. It is true constant because you can't set it, but you can get it whatever you want:

on constantPi()
    3.14159265359
end constantPi

get constantPi() --> 3.14159265359
set constantPi() to 10 --> Access not allowed

Note: do not remove parentheses in the last code line, otherways you create additional variable constantPi instead of your "constant"

Upvotes: 0

Ted Wrigley
Ted Wrigley

Reputation: 3184

There is no way to explicitly define a constant in AppleScript. There are three approaches that might suffice, depending on what you're trying to achieve.


If you're using a Scripting Definition (sdef) in your library, you can add an enumeration to define terms you want to reserve, then handle them by cases in code. For instance, if you want to assign constant values to the terms 'tau', 'gamma', and 'lambda', you define an enumeration like so:

<enumeration name="Constants" code="CVal" description="defined constant values.">
    <enumerator name="tau" code="tau&" description="tau constant."/>
    <enumerator name="gamma" code="gam&" description="gamma constant."/>
    <enumerator name="lambda" code="lmd!" description="lambda constant."/>
</enumeration>

Then in code have a handler to resolve them, and call it when needed:

to resolveConstant(cnst)
    if cnst is tau then
        return pi/2
    else if cnst is gamma then 
        return 17.4683
    else if cnst is lambda then 
        return "wallabies forever"
    else
        return missing value
    end
end resolveConstant

Create handlers for each of your constants, and call them as functions:

on tau()
    return pi/2
end tau

set x to 2 * tau() * 3^2 -- x = 28.2743

If you want true constants, you're going to have to shift away from a script library and code a faceless background app (like System Events or Image Events). From the perspective of an end-user it won't make much difference, save that they'll have to authorize having the application run, but it might mean a serious increase in labor on your end.

Upvotes: 1

Related Questions