Run Method stored in string

Is it possible to run a method by having the method name provided dynamically from a string value?

Currently, I have something similar to below. The only way I’ve found to call the method is via a If statement:

Dim methodNameIs As String
methodNameIs = "myMethod"

If methodNameIs = "myMethod" Then
myMethod
End If

But I would like to be able to skip to If statement and simply run the method name stored within “methodNameIs”

I have seen this topic:

https://forum.xojo.com/t/call-a-method-with-a-variable-name/29245

But I can’t fully get my head around the AddressOf / invoke side of things and it seems over complicated for what I’m trying to achieve above.

Any help would be much appreciated.

Use delegates and add the address to a dictionary value, put the string “name” in a key for the dictionary value.

1 Like

What @DerkJ said.

Dim Methods as Dictionary
Methods.Value("CallMyMethod") = AddressOf MyMethod
Methods.Value("CallAnotherMethod") = AddressOf MyOtherMethod

Dim s as string = "CallMyMethod"
Methods.Value(s).invoke
6 Likes

Thank you Julia, I think I get it now.

Using your example as a reference. If I created a method called “MyThirdMethod”, am I correct in saying I wouldn’t be able to invoke that without first adding it to the dictionary? e.g.

Methods.Value("MyThirdMethod") = AddressOf MyThirdMethod

There’s no way to assume that the string value is a method name and invoke it without a dictionary lookup?

Hopefully that makes sense.

It might help to know why you need this and what your goal is. There might be a better way.

1 Like

You can always ask the dictionary:

if  (Methods.HasKey("SomeMethod")=False)  then
  // Can't invoke it !
end if
1 Like

or xojoscript

Correct. I usually have a method called “LoadDelegates” or some such that I call when the window or app opens, where the dictionary is loaded with all the methods I might want to invoke.

Thank you all for your replies and your time

To answer you directly, Kem. I have a Timer that is triggered when a SQL query takes place within a Thread. The Timer checks to see if the Thread has completed and if so calls a Method that is specified as a parameter in the original Method. Generally the ending Method will be where the UI is updated (if needed).

In short, I guess I’m trying to write as little code as possible to keep things as simple as possible.

With Julia’s example I can achieve this, I guess I was just hoping for a very simple “runAsMethod(String)” that would process the entire thing without the need to link String to Method up front. Call it laziness I guess :slight_smile:

Again, thank you all for your time and help.

Why don’t you make the parameter the delegate to call rather than its name?

2 Likes

Store the delegate, your timer fires it later.

Or raise the event directly from the Thread when it’s done.

If this is the only thing his timer does, it could enable the removal of such the timer. But if such delegate involves access to the UI, it adds another class of complexity just to fire it (Thread.UserInterfaceUpdate) or firing another timer from it.

You could call Timer.CallLater(0, AddressOf ASubMethod)
(this is actually calling it directly on the main thread as soon as it can)

He. As I mentioned. :smiley:

No need of AddressOf as the delegate ( that once was an AddressOf Method ) is stored, just pass the variable as

Timer.CallLater(0, aStoredDelegateMethod)

1 Like

Actually, what I wrote previously:

won’t compile. You need to cast the variant from the dictionary as a delegate before you can invoke the method.

Add a delegate to your module or window or class, using the Insert menu of the IDE. Once you’ve created a delegate and called it, say, “MyMethodCaller”, cast the variant like this:

MyMethodCaller(Methods.Value(s)).Invoke

I don’t think you can declare a delegate locally with Var or Dim, I think you have to insert it with the IDE, but I could be wrong about that.