Generate compiled applescripts using applescript?

How do I use an applescript to create other compiled applescripts? The only starting point ive found is in the Standard Additions dictionary with: store script ‘script’
I tried to do this with a string for the script parameter but that didnt work.

Thanks, Eric

Here’s an example:

script ScriptObj
display dialog "Hi." 
end script
tell application "Finder"
set desktop_path to desktop as string 
end tell 
set file_spec to file (desktop_path & "CompiledScript") 
store script ScriptObj in file_spec -- xtra run script file_spec

Sorry about that. Hope I get it right this time.


script ScriptObj
display dialog "Hi."
end script
tell application "Finder"
set desktop_path to desktop as string
end tell
set file_spec to file (desktop_path & "CompiledScript")
store script ScriptObj in file_spec
-- xtra

run script file_spec

Thanks!! That works great.

There is one thing that I dont understand though. I am generating multiple scripts and saving them from a loop. I use a variable in the generated scripts that changes each iteration of the loop, so it should be different in each script. When I run the generated scripts they work as desired but when I look at them in script editor they all simply have the variable name(instead of the value). Where is the value being stored? I would rather it just insert the value as a constant instead of the variable name into the generated script.

Thanks again. Eric

One more thing :slight_smile:

Is there any way to save the script as an application like you can do from script editor?

Eric

This is the way it is - the value is stored within the variable, even though it appears otherwise when you view them in the script editor. Beware that recompiling these script generated scripts will lose that variable’s set value.

Perhaps it’s safer to save them as read only scripts (which can be done via a read only script application)?

Create an empty script application for use as a template or master and have your script duplicate that and then store the script into it.

Cheers,
Dave L.

Here’s an idea that is in the working, but, if anybody else can finish this or something better then great!. Your script will do these things:

  1. Create a folder to store all your stuff whose name changes in a repeat loop.
  2. Have your script duplicate an application that loads a compiled script and save it in the_folder. Note: the name of the compiled script will change also.
  3. Have your compiled script load a list of constants from a text file of which the name of it is stored in a list.

Basically, create a compiled script runner. The compiled script gets its constants values from a text file. I have to check on whether a compiled script holds properties or not.

Time to rest, Kel.

Be aware that ‘store script’ is used to store existing script objects to file, rather than to create new ones. If you wish to compile a string and run it as a script, use ‘run script’.

For example:

run script "display dialog "hello world""

To create an entire script using ‘run script’ is slightly more complex (note: you really ought to learn about AS’s script objects if you’re going to be doing this sort of thing). The following example generates very simple custom-assembled scripts and saves them to disk. :

set theName to text returned of (display dialog "Your name:" default answer "")

set theString to "
script
   -- This script belongs to " & theName & "
   display dialog "Hello " & theName & "!"
end script"

set theScriptObject to run script theString

store script theScriptObject in (new file with prompt "Save script as:")

This approach is useful when you want to generate a complete, bona-fide script on the fly. It’s not without its disadvantages, however. The main one is speed: in order to compile a string using ‘run script’, the AS compiler has to be loaded and unloaded each time. This is very slow; e.g. it takes about a second on my G3/300.

Here’s another approach to the problem which doesn’t need to assemble and compile strings; instead it uses a ‘constructor’ function to create script objects directly:

set theName to text returned of (display dialog "Your name:" default answer "")

set theScriptObject to newScriptObject(theName)

store script theScriptObject in (new file with prompt "Save script as:")

on newScriptObject(theName)
	script
		property myName : theName
		display dialog "Hello " & theName & "!"
	end script
end newScriptObject

The catch with this last example is that you can’t open and edit/run it from a script editor because you’ll lose the data that’s stored in property ‘myName’ if you do. It’s only suitable for storing into, and executing from, an empty applet - or for loading into another script using ‘load script’ and calling it from there. In many cases this is all you want anyway, so isn’t an issue, but you should be aware of this all the same.

So which method you use really depends on what your particular requirements are. Both have their uses.

BTW, you don’t need to use ‘run script’ to run a compiled script object. It’s quicker and simpler to call the script object’s ‘run’ handler from a tell block, like so:

script theScriptObject
	display dialog "Hello Joe!"
end script

tell theScriptObject
	run
end tell

This is all very powerful, complex stuff so try to spend a bit of time playing about and getting familiar with it. Try to do some background reading too: it’s a lot easier to do (and do well) if you’ve got some decent knowledge of the subject.

Oh yeah, and it also becomes easier to understand this stuff once you realise that all AS scripts are script objects, and that all script objects contain ‘run’ handlers. (This is not immediately obvious, as AS hides this sort of stuff to make things easier for beginners, but it’s there. The AppleScript Language Guide explains it all in more detail.)

HTH

has

The best approach I’ve found is to make a copy of an existing applet (even the creator script if it’s an applet) and load script into it.

[3/2/02 3:29:27 AM]

Hi Eric,

Sorry it took so long, but, I wasn’t feeling well this weekend. This example isn’t elegant and contains hardly any comments, but, should work. You may want to skip it because it may be hard to understand. First, save this as an application onto the desktop and name if “TheRunner”:

tell application "Finder"
	set my_folder_path to (folder of (path to me)) as string
end tell
-- get the constants 
set constants_file_ref to file (my_folder_path & "ConstantsList")
set ref_num to (open for access constants_file_ref)
try
	set the_constants_list to read ref_num as list
	close access ref_num
on error err_mess
	close access ref_num
	display dialog err_mess
end try
-- end get the constants 
set the_name to item 1 of the_constants_list
-- load the compiled script 
set compiled_script_ref to file (my_folder_path & the_name)
set ScriptObj to (load script compiled_script_ref)
-- end load the compiled script 
set constants_list of ScriptObj to the_constants_list
tell ScriptObj to run

Then, this is the ScriptMaker:

property names_list : {"Mary", "John", "Jane", "Frank"}
script ScriptObj
	property constants_list : {}
	set {the_name, the_index} to constants_list
	display dialog the_name & return & the_index
end script
set folder_paths to {}
set the_count to 0
tell application "Finder"
	set desktop_ref to desktop
end tell
repeat with i in names_list
	set the_count to the_count + 1
	tell application "Finder"
		set folder_path to (make new folder at desktop_ref with properties {name:i}) as string
		duplicate file "TheRunner" of desktop_ref to folder folder_path
	end tell
	MakeNewConstListFile({i, the_count}, folder_path)
	set file_spec to file (folder_path & i) as file specification
	store script ScriptObj in file_spec
end repeat
on MakeNewConstListFile(the_list, folder_path)
	set file_spec to file (folder_path & "ConstantsList") as reference
	set ref_num to (open for access file_spec with write permission)
	try
		write the_list to ref_num as list
		close access ref_num
	on error
		beep 3
		close access ref_num
	end try
end MakeNewConstListFile

This is the script application that you run.
gl, Kel.