KM8: Local and Instance Variables

@peternlewis, thanks again for giving us local and instance variables. Very, very useful.

Feature Request

I know you're going to shoot me for asking this, but I need to ask:
Could you please provide a way of viewing local and instance variables while a macro is running?

One UI would be to allow them in the Pref > Variables panel.

Use Case: Would greatly aid in debugging a macro.
Without being able to see these variables as we step through the actions makes it very hard to identify the problem sometimes.
I'm sure you understand, since you have used many software debuggers over the years.

Actually it just hit me: Maybe a better UI would be to have a Variables panel in the KM Debugger, you know, like the Chrome JavaScript debugger:

Thanks for considering this request.

1 Like

For now, the best solution is probably to use the Log action and tail -f or Console to watch the Engine.log file.

What is the JXA equivalent for the above codes? Thank you.

I don’t know. Perhaps someone who is better versed at JXA can answer.

I finally worked it out:

JXA Script to Get/Set Local & Instance Variables

var app = Application.currentApplication()
app.includeStandardAdditions = true

var kmInst = app.systemAttribute("KMINSTANCE");
var kmeApp = Application("Keyboard Maestro Engine")

var myLocalVar = kmeApp.getvariable("Local__MyVar",  {instance: kmInst});
kmeApp.setvariable("Local__FromJXA", {instance: kmInst, to: "Set in JXA Script"})

Here's my simple test/demo macro:

##Macro Library   Get Local Variables in JXA Script


####DOWNLOAD:
<a class="attachment" href="/uploads/default/original/2X/5/535ead5e89e0af65ad08addf4309b564e43a55ca.kmmacros">Get Local Variables in JXA Script.kmmacros</a> (3.1 KB)
**Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.**

---


<img src="/uploads/default/original/2X/0/04514eafd3fecd08b8b0b5f68b08793193cf8940.png" width="459" height="845">
4 Likes

Great! It would take me forever to figure it out, which means I would not be able to. Thank you.

1 Like

Not as good as watching variables update live but:
Here's a macro to display all current Instance variables. Easily modifiable to also show Global variables. Can't show any local variables (even ones defined in the macro).

I use it as a subroutine and just call it as needed while debugging.

Thanks for sharing.

That is proper behavior for local variables.
However, we can access local variables from AppleScript.
But I don't know how to get a list of local variables like I can with global variables:

set kmVarList to every variable whose name starts with kmPrefix

@peternlewis, any way to make this work for Local variables?

You could get them from the environment:

[test] Show Locals in Env.kmmacros (2.1 KB)

OK, thanks Tom. If we can get them from a shell script, then we should be able to get them from AppleScript. One issue with the shell script is that how can we tell if the underscores between words in the KM var name are actual, or just for the shell?

Good catch. Running this…

…I only get this:

That is: the first variable (the one without the underscores) is not in the environment. But it should be, I think.

Maybe something @peternlewis should have a look at.

I think the trouble is in your variable name. Your space-version and underscore-version are treated as if they’re the same (if I recall, the underscore replaces spaces in variable names in shell scripts).

Try naming them “Local Test Var One” and “Local_Test_Var_Two” and they’ll both show up in the environment (with underscores not spaces). They did in my test.

But the issue remains that looking only at the environment we have no way to tell whether or not the actual variable name contains spaces or underscores.

Yes, given that spaces must be underscores in shell scripts.

The point is that Tom’s first variable isn’t being skipped by the shell script. It’s indistinguishable from his second as far as the shell script goes. And so it has the second value when listed.

The workaround, it would seem, is to use one or the other (spaces or underscores) and not mix them.

Nope. You cannot list local or instance variables from AppleScript. There is no way to see the instance while using OSA-style AppleScript interfaces.

The For Each Variables collection will see Local and Instance variables. But it will only see Local variables in the same macro with the collection. I cannot see Local variables in other macros.

That is correct, if you have variables that only differ by spaces/underscores, you will not be able to see both in the environment variables.

Executed shell scripts will not see any more variables than the For Each Variables collection.

That is correct. Use one or the other.

Exactly.

AppleScript "variables" cannot see Local or Instance variables (not possible). I could add some other method of listing variables that includes the instance parameter, but I doubt this will ever happen.

Variables whose names are only different by space/underscore changes will only be seen as one or other by environment variables. I doubt this will ever change.

1 Like

One more reason not to allow spaces in variable names -- it just adds confusion, for little benefit.

I don't understand what you mean, since obviously with KM 8.0.3 AppleScript can get KM Local variables.

So I suppose the only way to get a list of KM Local variables from AppleScript is to parse the shell script output that @Tom used, correct?

The getvariable command is a custom Keyboard Maestro thing. I can add or change the parameters any way I want, so I can sneak in the hack instance.

The variables is a class in the Open Scripting Architecture (OSA) thing. It is handled largely by the system and has no extra parameters.

No. The only way to get Local Variables is to look at them from within the macro, using the Variables collection within the macro. You could use the Execute AppleScript/Shell Script, but that would be less efficient and incapable of seeing all the variables.

The macro @kvanh posted shows Local Variables - it just only shows the Local Variables that are currently within scope, which does not include the Local Variables from the macro that called it (since they are not within the macro's scope), only the Local Variables in the Display Instance Variables macro.

Ehm, yes, the point of the demo was to show that :wink:

1 Like

I am trying to pass local variables to a Shell Script using the Shell Script action, and the fact that “Local X” contains a space seems to mean the variable isn’t getting passed to the shell script. So I avoid using local variables. I’m not sure what the best solution to this is. I suspect that the vast majority of my variables are local so to be honest I would prefer the default to be local and some indicator to indicate global. That’ll never happen, of course. But as long as I’m talking about features that won’t happen, I’d like variables to have several options:

  1. Deleted at end of macro (“Local variable”)
  2. Deleted at end of KM engine shutdown
  3. Deleted at end of day
  4. Deleted at system reboot
  5. Deleted never (“global”)