If you run the script below in Script Debugger, you can see on the right side the list of “stacked” handers at any momento of the script, which is very convenient for positioning a line of code during the running when in a long script.
I wonder if it is possible to “extract” this information from within the script with a command such as getMyStackList.
Thanks!!!
on run
handler1("Luciano") --> Stak: 1.Run
end run
on handler1(someText)
display notification someText --> Stak: 1. Run; 2. handler1
set moreText to someText & " from handler1"
handler2(moreText)
end handler1
on handler2(moreText)
display notification moreText --> Stak: 1. Run; 2. handler1; 3. handler2
set evenmoreText to moreText & " and from handler2"
handler3(evenmoreText)
end handler2
on handler3(evenmoreText)
display notification evenmoreText -- Stak: 1. Run; 2. handler1; 3. handler2; 4. handler3
set evenevenmoreText to evenmoreText & " from handler3"
getMyStackList --???? Is this possible ??
end handler3
Can I ask you how (just the concept behind how) SD traces the stack list?
Trace the steps down it is quite simple, I cannot see an obvious way to trace the return steps.
If you cannot answer - since it might be a legally protected information - I completely understand that.
Thanks anyway !
I think, using global variable, you can trace were the script is each moment. Run following script and stop at different moments, to see were it is. Maybe, I don’t understand the question correctly:
global trace
on run
set trace to {"1. Run"}
delay 1
handler1()
delay 1
set end of trace to "1. Run"
end run
on handler1()
delay 1
set end of trace to "2. handler1"
handler2()
delay 1
set end of trace to "2. handler1"
end handler1
on handler2()
delay 1
set end of trace to "3. handler2"
handler3()
delay 1
set end of trace to "3. handler2"
end handler2
on handler3()
delay 1
set end of trace to "4. handler3"
end handler3
Basically it injects a whole lot of instrumentation code and interposes its own OSA component.
I updated my test to more correct. The delays is not required. They are only for testing purposes. To give you more time to stop the script at any execution point. You can remove all of them in the real-life script.
Thanks to both.
@Robert:
I was thinking along the same line, with this script (which is based on your input), which now populates and de-populates the global ‘trace’:
global trace
on run
set handlerName to "Run"
set trace to {handlerName}
delay 0.2
handler1()
delay 0.2
checkHandlerList(trace, handlerName)
end run
on handler1()
set handlerName to "handler1"
checkHandlerList(trace, handlerName)
handler2()
delay 0.2
checkHandlerList(trace, handlerName)
end handler1
on handler2()
set handlerName to "handler2"
delay 0.2
checkHandlerList(trace, handlerName)
handler3()
delay 0.2
checkHandlerList(trace, handlerName)
end handler2
on handler3()
set handlerName to "handler3"
delay 0.2
checkHandlerList(trace, handlerName)
beep
delay 0.2
checkHandlerList(trace, handlerName)
end handler3
on checkHandlerList(thelist, theHandlerName)
{thelist, theHandlerName}
if last item of thelist is theHandlerName then
set thelist to reverse of (rest of (reverse of thelist))
else
set end of thelist to theHandlerName
end if
set trace to thelist
end checkHandlerList
To make this approach more useful for debugging errors, you can use script-wide try block. To get trace when error occurs. For example, this way:
global trace
on run
try -- script-wide try block
set trace to {"1. Run"}
delay 1
handler1()
delay 1
set end of trace to "1. Run"
on error
return trace
end try
end run
on handler1()
delay 1
set end of trace to "2. handler1"
handler2() -- error occurs here (handler2 is absent)
delay 1
set end of trace to "2. handler1"
end handler1