Pass arguments to script

Is there a way to specify command line arguments to a script before starting to debug? I have a script that begins

on run argv

But I can’t run it in ScriptDebugger without passing arguments.

You can do a test like this:

on run argv
	if (argv = me) then
		set argv to {1, 2, 3} -- whatever
	end if

It would be nice if there was an option on the Script menu or somewhere else to set these before running the script.

TL;DR: See the Develop > Run chapters of the SD Help.

Long anwser: While it’s a bit clumsy, this works:

  1. Save your script as (e.g.) foo.scpt, with a run handler like this:

    on run argv
    end run
    on _run_(argv)
      -- the actual code to run goes here
      return length of argv -- simple example
    end _run_
  2. Create a new test script containing a call to _run_:

    _run_({1, 2, "three"})
  3. With the test script frontmost, select Script > Parent Script > foo.scpt

  4. Run the test script.

The _run_ call will be forwarded up the OSA delegation chain from your test script to its parent, where it’s handled. You can create as many of these test scripts as you like; handy for testing the handler with different values.

(Just be aware that if your main script stores values in properties/globals, those values will persist between runs. If you want to “reset” the script so each test runs cleanly, unaffected by the previous test, you will need to recompile each time.)

What is slightly annoying here is that a test script can’t just say:

continue run {1, 2, "three"}

If you know how OSA/AS’s message passing/delegation operates then you’d expect this to work nicely, but all that happens is AS throws a “Can’t continue run” error. (I’m guessing this is an OSA/AS limitation, not an SD one, but it’s been years since I last spelunked OSA so memory’s fuzzy.

One disadvantage of this delegation approach: if you save and close the test script and then reopen it, it does not remember the Parent Script so you have to select it again.

A slightly different approach is to use Script Debugger’s scripting support to send an Apple event instead:

tell script "foo.scpt" to _run_({"blah", "blah"})

Though again, you cannot just say:

tell script "foo.scpt" to run {"blah", "blah"}

as AS/OSA/SD similarly refuses to send the run call to the target script. AS has particularly baroque rules for determining the target of keyword commands, which frustrates what ought to be a simple and intuitive logic. But it works fine for handlers that have user-defined names.

Advantage of using this approach: the target script’s name is hardcoded in the test script, so you don’t have to fiddle with the Parent Script menu whenever you reopen the test script in SD. A possible downside: the _run_ call is sent via Apple events, not passed natively from script to script. AEs can be a pain if you need to send complex values (e.g. a reference to another application’s objects cannot pass cleanly through an AE), but that won’t be an issue if your argv is just a list of strings/numbers/other simple types—which I imagine it is.

And yes, it would be nice to have a Script > Execute > Run… option, but it’s not something most SD users would need, so probably isn’t worth the labour for Mark to implement [1] when the above techniques are already “good enough”.


[1] Besides, it’d make more sense for SD to support a full unit testing framework, allowing multiple automated tests to be run for one/some/all handlers in your script. I wrote a nice one, TestTools, many years ago but can’t really recommend it as there’s a really obscure bug deep in AS’s OSA support that would randomly cause it to glitch. (Not often, but often enough to be frustrating. AS bugs and omissions just make everything a pain.:/)