eval?

Does Applescript have a function equivalent to Javascript’s or PHP’s eval()?

The closest I’ve been able to come is the run script command. However, this doesn’t appear to work on user defined subroutines. Given the following script


-- will display the dialog 
test("This is a test") 

-- will also display the dialog 
run script ("display dialog "this is a test"") 

--throws an error 
--<> doesn't understand the test message 
run script ("test("This is a test")") 

on test(theString) 
display dialog theString 
end test 

The first two commands perform as expected, the third throws an error.

Any natural language mystics out there?

I’m not an expert on this, but I think I know what’s wrong with the third example. It’s trying to run a subroutine that is NOT part of the script. When you do a “run script” command you are asking AppleScript to run an independent unit separate from the current script.

I don’t know if there’s anyway to get the “inner script” to recognize a subroutine (handler, in AppleScript-ese) outside of its scope.

What does the eval() function in php do, and why is it better than simply calling the function name manually?

Hmm… thanks to Matt Neuberg’s excellent book, I figured out a way to do what you are trying. Basically, you can pass an argument into the script so that it can refer back to your scope.

run script ("on run {inArgs}
(topLevel of inArgs)'s test("This is a test")
end") with parameters {topLevel:me}

on test(theString)
	display dialog theString
end test

Not sure if this is the best way to do this but I hope it helps!

Hi,

Nice one redsweater. Here’s another way but it only runs when the script is saved as an application. Here I named the script app “MyScriptApp”.

run script (“property parent: application “MyScriptApp”
t(“This is a test”)”)

on t(theString)
display dialog theString
end t

EDITTED: this gets the name:

set my_name to (name of (info for (path to me)))
set p_text to “property parent: application “” & my_name & “”” & return
run script p_text & “t(“This is a test”)”

on t(theString)
display dialog theString
end t

gl,

Actually, you’re probably better off specifying the complete path, not just the name of the application in case you have more than one application with the same name (this also saves a few steps as you don’t have to get info for the app):

Also, using redsweater’s method, I would modify it a bit like so:

Jon


[This script was automatically tagged for color coded syntax by Convert Script to Markup Code]

Good, except for a couple of caveats:

  1. Because ‘run script’ is an osax, what gets passed to the ‘run {inArgs}’ handler is a copy of the main script, not a reference to it. That means your sub-script can’t modify properties in the main script. (This may not always be a disadvantage, mind you.) It also makes it slower; though ‘run script’ is pretty slow anyway, and this is only a problem if you’re calling it a lot.

  2. ‘run script’ may blow up when passed very large, complex values due to brittleness and internal limitations in the AppleScript interpreter.

To get around these problems, use ‘run script’ to compile and return a script object, then call that object’s handler(s) locally, e.g.:

on test(s)
    display dialog s
end test

set scriptObj to run script "
    script
        on doSomething(mainScript)
            mainScript's test("This is a test")
        end doSomething
    end script"

scriptObj's doSomething(me)

Best solution, of course, is to avoid evals whenever possible. The number of times you genuinely need an eval() is considerably smaller than the number of times you only think you need it. Aside from the security implications there’s usually simpler, non-hokey ways of achieving the same ends in-code.

HTH

Thanks all for the advice and scripts. I learned more about the Applescript object model than intended :slight_smile:

I promise only to resort to the hokey when absolutely necessary (like when the pokey shows up)