*** Disclaimer - this is no longer a problem I’m actively grappling with in order to get things done, so do not put time into this out of altruism. Only mess with this for educational purposes. ***
Given a library file named “Test Library.scptd,” saved in the user’s Script Libraries folder, contents:
on return_path_to_me()
return path to me
end return_path_to_me
When I call the “return_path_to_me()” function with the library loaded, the resulting path is reliably the path to the parent script.
ie,
set loadedAdditionsPath to ((path to home folder as text) & "Script Libraries:Test Library.scptd") as alias
set loadedTestLibrary to load script loadedAdditionsPath
tell loadedTestLibrary to set pathReturned to return_path_to_me()
Will reliably return the path to the parent script, never the path to Test Library.scptd.
That’s great.
When I skip the “load script” and do this:
tell script "Test Library" to set pathReturned to return_path_to_me()
the path returned is either the path to the parent script calling it, or the path to the library itself… whatever it feels like returning, as far as I can tell.
I spent a while trying to create reproducible test cases to submit here… “run this script and it returns the parent path, then make these changes and it returns the library path…” but I thought I was losing my mind, I was unable to get anything to work reliably. I’d have script #1 that was returning the parent path, leave it alone and try to make script #2 that returned the library path to show you, finally get script #2 to return the library path (but not sure why), then went back to script #1 that had no changes since last run, re-run it, and now it too returned the library path.
When I first started testing this to see what happened, I was getting the parent script path, and I wrongly assumed that would be consistent and went ahead and deployed a script to our users making use of this. That library function is called identically from multiple scripts, and it was returning the parent path when called from one, but the library path when called from another.
I duplicated the whole library under a different name, and called from a copy of the identical script (except calling the renamed library), and it is returning a different path between the two.
So I just made a separate library that we use the “load script” command with, that contains the handler that uses (path to me), and problem solved. But I wanted to post here anyway as a curiosity, in case any of the usual suspects want to explain what’s going on.
This post is already on the long side, but I know the standard question (and rightly so), is “what are you trying to do?” Half the questions posted, the best answer is “stop trying to do that - do something completely different to get your desired result.”
So I’ll try to be concise:
Dozens of scripts deployed, multiple people working on them. Our primitive “version control” is a “test” folder where we work on scripts, and a “deploy” folder with copies of the same scripts everyone runs.
But we also have a large and growing library, and testing that is kludgy. Deploying a broken copy of the library can take down a dozen scripts.
So I want all scripts to call the “test” version of the library iff the script is running from the “test” folder, and the “deploy” version of the library if running from the “deploy” folder. The “deploy” folder is just named “Scripts.”
Our standard company library is “ROT Additions,” So I was starting every script with:
tell script "ROT Additions" to set ROTA to get_rot_additions()
Here’s get_rot_additions() from “ROT Additions”
on get_rot_additions()
tell application "Finder"
set thisScriptFolder to the name of the container of (path to me)
end tell
if thisScriptFolder is not "Scripts" then
try
set pathToTestROTAdditions to ((path to home folder as text) & "Dropbox:Test:Script Libraries:ROT Additions.scptd")
set ROTScriptingAdditions to load script file pathToTestROTAdditions
on error
display dialog "It appears you're running a development copy of the script from the \"Test\" folder, but the development copy of the library ROT Additions was not found." buttons {"Cancel", "Use Deployed Copy"} default button "Cancel"
if the button returned of the result is "Use Deployed Copy" then set ROTScriptingAdditions to script "ROT Additions"
end try
else
set ROTScriptingAdditions to script "ROT Additions"
end if
return ROTScriptingAdditions
end get_rot_additions()
Then all future library calls are done with “tell ROTA to…”
So all this seems to work fine as long as I load the script containing the “get_rot_additions()” handler.
We deploy scripts from the “Test” folder to the “Deploy” folder by running a Script Debugger script that archives an old copy, saves the new copy in “Test,” and saves a run-only new copy in the “Deploy” folder. It occurred to me we could always use references to the “Test” library when coding, and have the script we use to deploy also find-and-replace to the “Deploy” library for the copy saved to our “Deploy” folder. A live handler just seemed more elegant to me.
Thanks in advance for any thoughts,
Tom.