How to Use "Execute Subroutine"? (v10)

Hi,

Can someone show me an example of how to make use of Execute Subroutine? It came with v10 and seems to be a very useful feature.

Having no programming background, I don't quite understand this concept of "subroutine" and don't know how to make use of it. I thought Execute a Macro is already a "subroutine" macro.

Just by reading the wiki, it looks like a similar action to Execute a Macro. But apparently, it is different.

When right clicking a macro, I can choose the option:
image

I then pasted it to a new macro:

It looks almost identical to Execute a Macro. However, when I execute it, I get this notification:

image

Also, I have no idea about how to pass parameters or get results from the subroutine action.

1 Like

Have you taken a look at the new trigger (subroutine trigger) which lets you add one or more parameter names:

action:Execute a Subroutine [Keyboard Maestro Wiki]

1 Like

Here for example – three copies of the same macro, differing only in which subroutine is selected:

Obtaining a value from a subroutine Macros.kmmacros (19.9 KB)

With the same input (some numeric lines, in this case)

3
7
11
17

They produce 3 different outputs, varying with their choice of sub-routine:

III
VII
XI
XVII
6
14
22
34
9
49
121
289
9 Likes

Thank you very much, @ComplexPoint.
I think I understand how it works now.
The parameters are a bit like the parameters in the plug-ins.
The Execute a Subroutine action is closer to functions than Execute a Macro in that it explicitly passes as many parameters as needed and returns a result (if set).

Execute a Macro can take up to 1 parameters, which maybe split into segments, each working as a parameter. In addition, Execute a Macro can use global variables and instance variables.

The primary difference, as far as I can see, is that Execute a Subroutine action is more explicit in handling parameters and returning results.

2 Likes

Same here. But I have played around and think I am beginning to see some real world uses for this.

I have an existing Group of Macros that will open Finder Folders. Each Macro has a different Path and calls a Sub Macro to do the actual work of determining if I am in the Finder (opens the Folder in one way) or if I am in a Save As Dialog (opens the Folder in a different way).

I have adapted this to the Subroutine and Parameter approach.

The Subroutine does all the work and its "Parameter" is the file path. This value has been sent to it by the Calling Macro.

The Parameter in the Subroutine has "LOCAL" at the head of its name so that it doesn't persist after the run. And it is referenced just like a Variable in the Submacro (in fact it appears to be a Variable to all intents and purposes).

Interestingly the "LOCAL" part of its name gets stripped off in the Action that calls it.

Parameter is defined like this in the Subroutine:

But is referenced like this in the Caller Macro:

And the Parameter seems to be referenced just like a Variable in the Subroutine itself:

So, I am sure this is not exactly how Subroutines are intended to be used but in this case it allows me to have one Subroutine that does all the work and a whole series of Caller Macros that have just one Action in them - i.e. the Action that calls the Subroutine and has the actual folder path to pass to the Subroutine.

(To try this Example Macro out just change the file path in the Magenta coloured Action to a real folder path on your system.)

EXAMPLE Go To Folder in Finder or Save Dialog Macros.kmmacros (5.9 KB)

The Calling Macro looks like this. This is the Macro where you need to change the File Path to a real one on your System. And you would make copies of this Macro, just with different File Paths:

And the Subroutine Macro looks like this:

I'm sure there are going to be many more sophisticated uses of Subroutines (my example doesn't make any use of sending the results back to the Calling Macro) but for me this is a start of understanding the concepts.

EDIT - Why would I have a Caller Macro and this Subroutine? Why not just have all the workings in the Caller Macro? Because - this way if I discover the Subroutine needs to be adjusted to work well (i.e. a pause time between Actions to be changed) I only need to edit one Macro not all the Caller Macros.

EDIT 2 - Just discovered something really cool. If the Parameter name is changed in the Subroutine it auto-updates in all the Calling Macros. I thought "FolderPath" might be a better name than "FilePath" and as soon as I changed it in the Subroutine all the Calling Macros updated as well:

Changed Parameter name in Subroutine:

All references auto-update in Calling Macros:

6 Likes

That’s a great example @Zabobon !

This is similar to one of the changes cited in the KM10 release notes:

  • Remove “Instance ” and “Local ” from variable names in Prompt For User Input form.

I wonder if this is intentional or a mistake for subroutines? @peternlewis ?

1 Like

Thanks a lot, @Zabobon, for the detailed example!

I remember Peter said somewhere that the parameters are essentially variables. They act like variables. Therefore, the removing of "instance" and "local" are to be expected. It's not limited to these two words. The same applies to double underscores:

image

image

2 Likes

Great. Very good to clarify.

And a question for @peternlewis - I'm assuming that unless the Parameters have "local" or "instance" in their names they will persist just like Variables? I'm not sure if it really matters but just for the good practice of cleaning up after Macro runs.

Subroutine Parameters Documentation Recommendation

2 Likes

Yes - from the caller point of view, you want to know about the parameters, rather than the type of the variable.

Correct.

So good practice will be to use Instance or Local variables for your parameters.

3 Likes