-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Execute object macros within conditionals #111
Conversation
I'll also fix #102 with this PR (a simple regexp change to make the |
@kirsle I've not find any public method allowing to call a redirection tag {@redirection trigger} directly from a subroutine, in the source code. Did I miss something ? This would be very useful as you seem to not want asynchronous object macros be callable in a condition, as a workaround guessing you do the conditional comparisons directly from the subroutine. |
@davidchriqui the Implementation of the # Inline redirector
match = reply.match(/\{@([^\}]*?)\}/)
giveup = 0
while match
giveup++
if giveup >= 50
@warn "Infinite loop looking for redirect tag!"
break
target = match[1]
@say "Inline redirection to: #{target}"
subreply = @_getReply(user, target, "normal", step+1, scope)
reply = reply.replace(new RegExp("\\{@" + utils.quotemeta(target) + "\\}", "i"), subreply)
match = reply.match(/\{@([^\}]*?)\}/) What you could do:
|
What about using replyAsync instead of reply (using async subroutine) ? Can you give a working example please ? |
Are you doing this inside a condition? (Like, The reason I think object macros in conditions shouldn't be asynchronous is that RiveScript wants to check the condition "now" to see if it's true. So what happened up to that point was: the user's message matched a trigger, RiveScript is trying to find a reply for them, the trigger has conditions to check, and it needs to evaluate each condition and see what its return value is. If the condition is asynchronous, that can oftentimes mean the object macro will take some indeterminate amount of time to finish (e.g. call out to a web API or something). If the object macro takes, say, 5 seconds to resolve its promise, then RiveScript would be essentially frozen solid for 5 seconds waiting to see how that object macro finishes, and if it doesn't even return a "true" answer it just wasted a lot of time for nothing. Asynchronous object macros return a Promise object, and
I don't know how that will behave in a conditional, though. It likely won't work, because the condition internally doesn't know how to follow/resolve promises. And if I wanted to make it try to resolve promises, I don't even know how I'd go about doing so, given that |
If you really need to do something asynchronously like this, it might be better to just keep things simpler and do 100% of your work inside the object macro.
So instead of doing stuff like, (On a side note, even if the conditions could work asynchronously, if you had something like the above where it calls some API and then gives multiple answers depending on the result... each answer would be its own separate |
After more experimentation, supporting asynchronous object macros (that return promises) in the left side of a conditional line can't work. I was hoping I'd be able to call So, when the left side of the condition is evaluated each object macro is called with an explicit I updated the documentation in the |
This also fixes #123. |
This change fixes a regression caused by #78 where
<call>
tags inside conditionals weren't being fully executed, due to the actual processing of the<call>
tag being moved into a separate function fromprocessTags()
and the condition checking code didn't call this new function.@callmephilip can you look at this code change and verify that it makes sense? One thought I have about it is that asynchronous object macros shouldn't be callable in a condition, because RiveScript requires the result to be ready "now" for comparison checking (I might need to pass in an explicit
false
for theasync
parameter, regardless of the one the user requested).This will fix #107.