rivescript-java icon indicating copy to clipboard operation
rivescript-java copied to clipboard

Using object macro within topic

Open bhatmanjokes opened this issue 7 years ago • 3 comments
trafficstars

I am trying to use the object macro within topic and it is failing. However the code snippet before topic is running Would you please tell me where the error lies

Below is the code snippet of it

+ load the * data set 
* <call>loadDataset <star></call> == pass => Dataset is now \s
^ loaded. You can access the table in the main view. {topic=load}

> topic load

  //This will match if the word "load" exists ANYWHERE in the user query
  + [*] load [*] 
  * <call>loadDataset <star></call> == pass => Dataset is now \s
  ^ loaded. You can access the table in the main view. {topic = random}

< topic
- Data set not found 

bhatmanjokes avatar Jun 29 '18 16:06 bhatmanjokes

  + [*] load [*] 
  * <call>loadDataset <star></call> == pass => Dataset is now \s

The <star> tag won't work there because there aren't any capturable wildcards in the trigger. The [*] is optional so it doesn't get captured into a <star> tag.

So it's probably effectively doing <call>loadDataset undefined</call> which maybe doesn't return "pass" so the condition fails.

Instead you'd probably want to set a user variable; before going into the topic, when you do have the right <star> value, do <set loadDatasetSource=<star>> and then inside the topic:

  + [*] load [*] 
  * <call>loadDataset <get loadDatasetSource></call> == pass => Dataset is now \s

Also: it's good practice to always include at least one -Reply when you're using conditions, in case all the conditions fail, so you have a fallback reply to return.

kirsle avatar Jun 29 '18 17:06 kirsle

As per your suggestion I tried to modify the code and it still isn't working for me

! version = 2.0

//Loading the data set 
+ load the * data set 
* <set loadDatasetSource<star>><call>loadDataset <star></call> == pass => Dataset is now \s
^ loaded. You can access the table in the main view.{topic=load}
> topic load
	
	+ [*] load [*]
    - <call>loadDataset <get loadDatasetSource></call> == pass => Dataset is now \s
    ^ loaded. You can access the table in the main view.{topic=random}

    + *
    - I don't get that.
    - I'm sorry!
    
< topic
- Data set not found!

bhatmanjokes avatar Jul 04 '18 12:07 bhatmanjokes

Hi,

First, don't mix the topic declaration inside the middle of the response like that. I think it would probably confuse the parser, which reads the source code line-by-line and tries to relate the current line to the most recently seen +Trigger, etc. -- so when it sees the > topic load and subsequently the [*] load [*] it would start populating data into a different trigger in a different topic than you intended.

* <set loadDatasetSource<star>><call>loadDataset <star></call> == pass

I think the syntax here looks wrong.

  • <set loadDatasetSource<star>> isn't a complete <set> command. If I said "load the test data set" it would turn this <set> tag into <set loadDatasetSourcetest> and there's no =value part to set it to.
  • Also, you can't take the output of the <call> tag and put it into the <set> as a value. i.e., if this is what you were trying to do: <set name=<call>object</call>>. The <call> tags are processed at the very end, long after the <set> tags have already been dealt with, so the result of the <call> tag can't be processed in a <set> and the <set> you tried to use will probably get mangled and come out wrong in syntax anyway.

These issues aside, what do you want the bot to do? As you wrote it, it seems like the workflow would be like:

  1. The user says "load the test data set"
  2. The bot, in topic "random" matches the load the * data set trigger.
    1. Test the condition <call>loadDataset <star></call> == pass
      • Presumably loadDataset has a side effect of setting the user var loadDatasetSource
      • The function does something and returns the string "pass"
    2. The condition is true, so the reply is "Dataset is now loaded. You can access the table in the main view.{topic=load}"
  3. With the reply in hand, process the tags in it.
    • {topic=load} sets the user's topic to "load"
  4. Return the reply to the user.

And now the user is in the "load" topic, so on their next message to the bot:

  1. The user says something with the word "load" in it
  2. The bot, in topic "load" matches the [*] load [*] trigger.
    • Basically the same thing as above. You again call loadDataset and if it returns "pass" the second time, you set the topic back to "random"

Is it intentional to call the macro two times in response to two user messages? Or are you trying to chain these in sequence so that one user message results in both triggers being activated?

If it's the latter and you want both triggers to activate in sequence for one message, maybe the inline redirect {@} tag will work. In the condition reply side, => Dataset is now loaded.{topic=load}{@ load}. I haven't tested it but that might work.


Also, if you ever wonder what the bot is doing with your code, turn on debug mode and watch the terminal. When it goes and tests the *Conditions it will print out what the two operands ended up evaluating to (being like Test if pass == pass) and you can see if anything is going wrong or if tags are getting mangled or parsed weird, etc.

kirsle avatar Jul 06 '18 18:07 kirsle