Remove subroutine parameter cause a lot of trouble

NOTE this: I have a subroutine which has three parameters:
Local__Parameter_A
Local__Parameter_B
Local__Parameter_C
In practical use, I just find I am always using Global Variable
GlobalVar_A to pass Local__Parameter_A
GlobalVar_C to pass Local__Parameter_C
please see the picture. Left side is the SUB. Right side is the CALLER.


So after some days, for simplicity and optimization and beauty, i decide to remove
Local__Parameter_A
&
Local__Parameter_C

In practical, I remove Local__Parameter_A by clicking the red minus button on the left side of the parameter name.
Please see what happened.


The Local__Parameter_A is removed. But it's value was set to Local__Parameter_B.
And the value of Local__Parameter_B was set to Local__Parameter_C.
This is really crazy and hard to understand.

And then I remove Local__Parameter_C.
See what happened.


I lose Value-B.
WHAT DOES THIS MEAN?
If this subroutine has ten callers.
I need to check each one of these callers, and remember the correct 'Value-B' for each of them and set it back.
This is impossible.

So my question is that, why it works in this way.
If I remove Local__Parameter_A, I should lose value-A in all its callers.
If I remove Local__Parameter_C, I should lose value-C in all its callers.
Shouldn't it be like this????

For now i can't modify the parameters of subroutine.

This is not a bug but is mentioned in the KM wiki here: Subroutines [Keyboard Maestro Wiki]

Specifically this paragraph:

"Note that parameters are internally passed by index, so if you later change the Subroutine trigger, and add or remove parameters, or change the meaning of parameters, you will need to adjust the various Execute a Subroutine actions as well - you can get to them directly using the Callers menu in the trigger."

So I'm afraid you're going to have to go and do some further editing.

2 Likes

focus on the caller. Copy the caller as XML. I get this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Actions</key>
	<array>
		<dict>
			<key>ActionUID</key>
			<integer>15463811</integer>
			<key>MacroActionType</key>
			<string>Pause</string>
			<key>Time</key>
			<string>0.3</string>
			<key>TimeOutAbortsMacro</key>
			<true/>
		</dict>
		<dict>
			<key>ActionColor</key>
			<string>Purple</string>
			<key>ActionUID</key>
			<integer>15463812</integer>
			<key>MacroActionType</key>
			<string>ExecuteSubroutine</string>
			<key>MacroUID</key>
			<string>E0274DE8-2D8B-4011-BE30-292A13471BC2</string>
			<key>Parameters</key>
			<array>
				<string>GlobalVar_A</string>
				<string>value-B</string>
				<string>GlobalVar_C</string>
			</array>
			<key>ResultVariable</key>
			<string>Local__Output</string>
			<key>TimeOutAbortsMacro</key>
			<true/>
		</dict>
	</array>
	<key>CreationDate</key>
	<real>748349726.11989796</real>
	<key>ModificationDate</key>
	<real>748350165.60269701</real>
	<key>Name</key>
	<string>test subroutine - remove parameter part 2 - caller</string>
	<key>Triggers</key>
	<array/>
	<key>UID</key>
	<string>57DEC148-04D5-4A22-9E58-B6EE91DC229A</string>
</dict>
</plist>

NOTE that this part:

<string>GlobalVar_A</string>
<string>value-B</string>
<string>GlobalVar_C</string>

treat this XML as a text. And I can use Regex method to change this part into:

<string>value-B</string>
<string>GlobalVar_A</string>
<string>GlobalVar_C</string>

Because I want to keep the third one, So I make the third one the first.
Then I go back to SUB to remove the Local__Parameter_A & Local__Parameter_C
SO finally:
In SUB, I will keep Local__Parameter_B.
&
In Caller, I will keep the Value-B for just the Local__Parameter_B.

So my thought - my workflow was:
step 1: list all callers.
step 2: loop the list:
--1)convert item caller A to XML
--2)find the parameter part and change the order of lines to keep the Value I want at the front.
--3)apply the change to the caller the macro itself.

Now I stuck at the last step, after I modified the XML content, how to make the caller respond this adajustment? OR just an old question, Is there a way convert this new XML to a km macro?

I want to know if this is beyond my knowledge range

I think it's easier to see what's happening if you look at an abbreviated "ExecuteSubroutine" action in JSON format:

[
	{
		"MacroActionType": "ExecuteSubroutine",
		"MacroUID": "DD34783A-90A1-4022-9136-C5976A3E26BD",
		"Parameters": [
			"%ExecutingMacro%",
			"%ExecutingThisMacro%",
			"No actions with offloadable resources found",
			"1"
		]
	}
]

You can see that the parameter values are just stored in an array. The first one goes to the first parameter, etc.

One advantage of this is that you can change the names of the parameters without affecting any of the callers.

So what do you do when you want to make changes? First of all, if you haven't noticed this before, in your subroutine is a dropdown of all the callers:

image

That can help quite a bit.

The second thing is, try not to remove parameters - only add to them. If you need to, create a second subroutine with fewer parameters, and have it call the original subroutine. This way you can introduce it slowly over time.

The third thing is, think carefully about the order of your parameters, and put the ones that are most likley not going to change at the front. Then if you delete one of the lesser-used parameters, you only need to change those few places that actually pass the other parameters.