[quote=121433:@Oliver Scott-Brown]I have heard of CurrentMethodName. Is there an easy solution to getting the name of the method that called the current method, for example:
Sub MyMethodCaller
MyMethod()
End Sub
Sub MyMethod
System.DebugLog(CurrentMethodCallerName) //return 'MyMethodCaller'
End Sub
[/quote]
You can keep a log of currentmethodname changes in an array so all you have to do is look which name was before the current one.
An easy way would be to add a methodCaller parameter to the method which is being called:
[code]Sub MyMethodCaller
MyMethod(CurrentMethodName)
End Sub
Sub MyMethod(methodCaller as string)
System.DebugLog(methodCaller)
End Sub[/code]
Or you could do it by raising and catching an exception and examining the stack trace:
[code] dim methodCaller as string
try
dim n as new NilObjectException
Raise n
catch err as NilObjectException
dim s() as String = err.Stack
s = Split(s(1),"%")
methodCaller = s(0) //this would give the full path to the method, i.e. window1.mymethod, module1.mymethod, etc
's = Caller.Split(".")
'methodCaller = s(s.Ubound) //this would give just the name of the method and not the full path to it
end try
//methodCaller is now the name of the calling method[/code]
Sometimes you come across a question and shortly after you come across an answer to the question. That happened again when a few weeks ago I saw a thread on the forum where people debugging a problem wished for a simple way to know from where their methods were called. And then I ran across a [blog post] (http://www.realsoftwareblog.com/2012/05/debugging-tips.html) on the old REALbasic site where Thomas Tempelman addressed exactly that problem in quite a nifty way.
Basically he uses the fact that instances have a scope, a limited life time that ends when the method or event they are created in terminates. So he creates a MethodProfiler class with a Constructor and a Destructor that do the logging. When you instantiate a new MethodProfiler object then you pass it the name of the current method like this:
Sub myMethod()
dim myTmpObject as new MethodProfiler(CurrentMethodName)
Consequently when you create the class at the beginning of a method then the Constructor logs where that happens, and it stores the passed method name in its own mName property for later use in the Destructor:
Sub Constructor(name as String)
System.DebugLog "<"+name+"> Entered"
mName = name
End Sub
At the end of the method the MethodProfiler instance is destroyed and the Destructor is called - which logs that too:
Sub Destructor()
LogMsg "<"+mName+"> Exited"
End Sub
So in the log you can easily follow your apps progress.
But you can do much more with it too:
you can globally enable/disable debugging
you could measure the time that the method takes to execute
you could count the depth, allowing you to indent the output, making it more readable if you have nested calls you want to trace.
dim methodCaller as string
try
dim n as new NilObjectException
Raise n
catch err as NilObjectException
dim s() as String = err.Stack
s = Split(s(1),"%")
methodCaller = s(0)
end try
This code works fine on linux/mac but on windows err.stack is an empy rows array.