Search code examples
filescriptingapplescript

How to retain the value of 'me' when passing through another applescript


I have 2 applescripts... one called 'App' and one called 'Shell'. I want to be able to reference the name of the 'App' script within the 'Shell' script. What I've found so far is if the 'Shell' script reads anything with me in it, it seems to reference itself, instead of the 'App' script.

-- App.scpt

set appName to name of me


--Shell.scpt

tell application "System Events"
    
    set appScript to (load script file (POSIX file "/Path/To/App.scpt"))
    run appScript
    
    return appName
    
end tell

I've tried varying alternatives of what's written above with results such as errors, missing values, or 'Shell', which is incorrect... Any help would be much appreciated!


Solution

  • The term me always refers to the script that is currently being executed. The load script command returns the specified compiled script as a script object, which is treated as if it were local, i.e. the same as if it were in the script that loaded it.

    AppleScript has historically saved the values of script properties and globals in the script file itself (unless it has been made read-only), so that they will retain their values from the previous run. When using the load script command, you have access to all the handlers and properties/global variables of that script. The Script Editor can get in the way if you try to use it to set these initial values (as the script will be run locally), so you can use another AppleScript instance such as the Script Menu or osascript to run the app.scpt to set its initial values. Personally, I would set up App.scpt to be more flexible by accepting command line arguments, and include an initialization handler to (re)set whatever desired values:

    App.scpt:

    # script containing properties/globals/handlers to be loaded by another script - initialized via command line
    
    property myPath : missing value
    property myName : missing value
    
    global testing -- global variables can also be used
    
    on run args -- arguments passed via command line
       if args is not {} then
          if (count args) is 1 and (args as text) is "init" then
             init()
          else
             -- handle any other CLI arguments
          end if
       end if
       -- other script stuff
    end run
    
    to init()
       set testing to "This is some testing text." & return & "Some testing text this is."
       set myPath to (path to me) -- alias
       set myName to (name of me)
       -- (re)set any other properties and/or global variables
    end init
    
    on testDialog(theTitle, theText)
       display dialog (theText as text) with title (theTitle as text) -- whatever
    end testDialog
    

    Shell.scpt:

    # script to get get property/global values from a loaded script, initializing as needed
    
    set scriptPath to POSIX path of (choose file) -- or wherever
    set theScript to (load script scriptPath)
    try
       if theScript's myPath is missing value then error "script was not initialized" -- check for a value
    on error errmess
       log errmess
       do shell script "osascript " & quoted form of scriptPath & " init" -- initialize
       set theScript to (load script scriptPath) -- reload to get current values
    end try
    
    display dialog (theScript's myPath) as text with title (theScript's myName) -- display values from loaded script
    tell theScript to testDialog("Test", theScript's testing) -- use handler in loaded script
    

    Note that the load script command is from Standard Additions and scripts and applications have a name property, so you do not need to use System Events for those.