Alter detail in script from another script

I have a script set up that runs various user-defined actions. What I want to do is create a duplicate of the script, remove the user interaction and hard code the functions in as a default, so the user can just run the script and it all happens. Thing is, i want the user to be able to change the default easily, but without a constant “set default or run default” dialog.

I have come up with the idea that when the user selects from the set of functions, the script modifies the duplicate script to reflect this choice, thereby becoming the default. So whenever the user runs the duplicate script, it will automatically default to the last choice made by the first script.

Phew! Thats a mouthful.

Does anyone know how to modify one script from another, for example, modify the property TheVariable : “content” or something along those lines?

Outside of that, if anyone has any better ideas for how to implement this, please let me know.

I would appreciate your help.

Chuckles:D

If you are satisfied with being able to modify only the values of properties of existing scripts, then you can certainly do that with load script, set scriptObj’s prop to ., and store script. load script and store script are both from the Standard Additions OSAX that comes, well standard, with AppleScript installations.

Here is an example of what that might look like:

on run
	local scriptFileRef, scriptObj
	
	display dialog "Click a button to select an activity:" with title "Choose Activity" buttons {"Cancel", "Create and Adjust", "Adjust Only"} default button "Create and Adjust"
	if button returned of result is "Create and Adjust" then
		(*
		 * Create a script, save it, and run it from disk.
		 *)
		makeScript("This is the created script.")
		set scriptObj to result
		choose file name with prompt "Choose a file name for the new script:" default location (path to desktop folder) default name "Test Script.scpt"
		set scriptFileRef to result
		
		saveScript(scriptObj, scriptFileRef)
		
		set scriptObj to missing value -- Dump the in-memory script object, so that we can only run it from the saved file.
		
		run script scriptFileRef -- Run the script from the saved file, not from the script object that was in memory.
	else
		(*
		 * We didn't create a script, so have the user pick an existing script to adjust.
		 *)
		choose file with prompt "Choose a script to load and adjust:" default location (path to desktop folder) of type {"scpt", "scptd", "app"} without invisibles and multiple selections allowed
		set scriptFileRef to result
	end if
	(*
	 * Load a script, adjust its theAction and theMessage properties, save it, and run it from disk.
	 * The script to load can have been saved by Script Editor, Standard Addition's "store script", or anything else that can write a script that Standard Addition's "load script" is able to read.
	 *)
	loadScript(scriptFileRef)
	set scriptObj to result
	
	adjustScript(scriptObj, "This is the adjusted script.")
	
	choose file name with prompt "Choose a file name for the adjusted script:" default location (path to desktop folder) default name "Changed Script.scpt"
	set scriptFileRef to result
	
	saveScript(scriptObj, scriptFileRef)
	
	set scriptObj to missing value -- Dump the in-memory script object, so that we can only run it from the saved file.
	
	run script scriptFileRef -- Run the script from the saved file, not from the script object that was in memory.
end run

to makeScript(theText)
	script
		property parent : AppleScript
		property theAction : "dialog"
		property theMessage : theText
		to doIt()
			if theAction is "dialog" then
				display dialog theMessage with title "Dialog"
			else if theAction is "alert" then
				display alert "Alert" message theMessage
			else
				error "Unknown action: " & theAction
			end if
		end doIt
		on run
			doIt()
		end run
	end script
end makeScript

to loadScript(fileRef)
	load script fileRef
end loadScript

to saveScript(scriptObj, fileRef)
	store script scriptObj in fileRef replacing yes
end saveScript

to adjustScript(targetScript, theText)
	local displayType
	
	set displayType to choose from list {"dialog", "alert"} with title "Choose display type" with prompt "Choose a display type for the new script:" without multiple selections allowed and empty selection allowed
	if displayType is not false then
		set targetScript's theAction to first item of displayType
		set targetScript's theMessage to theText
	else
		error "No selection made, unable to continue."
	end if
end adjustScript

Like the comments indicate, it will work with either its own script, or any other script that load script can read. In this case, the loaded script must have the theAction and theMessage properties since those are what the adjustScript handler changes. For example, I tested the previous script with by loading a copy of the following script saved by Script Editor in each script format (normal script, script bundle, script app file, and script app bundle):

property theAction : ""
property theMessage : ""
property originScriptType : "sctpd" -- "scpt", "scptd", "app", or "app bundle"
on run
	display dialog originScriptType & "<" & theAction & ", " & theMessage & ">"
end run

Other approaches are possible, but usually more involved. If you have a code template that you want to change a bit and write out as a new script, you can do that in AppleScript with a combination of script objects, run script, and store script; with do shell script (or directly using the command line) and the command line tool osacompile; or by scripting Script Editor or some other scriptable AppleScript development environment.

Edit history: Added summary of some other script building approaches. Some rewording.

I was chatting with one of the web developers at work, he suggested I use a simple text doc with variable data, then have the script read from that. Never thought of that. Thanks for all your hard work, though. It will definitely come in handy at a later stage.