aichaos / rivescript-go

A RiveScript interpreter for Go. RiveScript is a scripting language for chatterbots.
https://www.rivescript.com/
MIT License
60 stars 16 forks source link

`RiveScript.SetSubroutine` type troubles #26

Closed meowgorithm closed 7 years ago

meowgorithm commented 7 years ago

I've noticed in the recent revision of this library RiveScript.SetSubroutine no longer works due to what appears to be a type mismatch:

For example, with the following code:

package main

import "github.com/aichaos/rivescript-go"

main() {
    bot := rivescript.New(nil)
    bot.SetSubroutine("test", func(rs *rivescript.RiveScript, args []string) string {
        return "Oh, hello."
    })
}

…results in the following error:

cannot use func literal (type func(*"github.com/aichaos/rivescript-go".RiveScript, []string) string) string) as type "chat/vendor/github.com/aichaos/rivescript-go/src".Subroutine in argument to bot.SetSubroutine

…which makes me think the issues lies in the fact that "rivescript-go/src".Submodule expects "rivescript-go/src".RiveScript as the first argument whereas "rivescript-go".RiveScript.SetSubmodule expects the local "rivescript-go".RiveScript as an argument, hence the type error.

meowgorithm commented 7 years ago

Okay, I just confirmed that my conclusion above is the case. The following technically works:

package main

import (
    "github.com/aichaos/rivescript-go"
    x "github.com/aichaos/rivescript-go"
)

main() {
    bot := rivescript.New(nil)
    bot.SetSubroutine("test", func(rs *x.RiveScript, args []string) string {
        return "Oh, hello."
    })
}

But, of course, it's a hack.

kirsle commented 7 years ago

The RiveScript type that the function takes is actually the 'internal' one from the /src sub-package. I didn't like having too much clutter in the root of the git repo so I put the majority of the code under /src and wrap it with the root package.

package main

import (
    "fmt"
    "strings"

    "github.com/aichaos/rivescript-go"
    rss "github.com/aichaos/rivescript-go/src"
)

func main() {
    bot := rivescript.New(rivescript.WithUTF8())
    bot.Stream(`
        + say * to me in reverse
        - <call>reverse <star></call>
    `)
    bot.SortReplies()

    bot.SetSubroutine("reverse", func(rs *rss.RiveScript, args []string) string {
        message := []rune(strings.Join(args, " "))
        for i, j := 0, len(message)-1; i < j; i, j = i+1, j-1 {
            message[i], message[j] = message[j], message[i]
        }
        return string(message)
    })

    reply, _ := bot.Reply("user", "say hello world to me in reverse")
    fmt.Printf("Reply: %s\n", reply)
}
meowgorithm commented 7 years ago

That makes sense. It’s a bit of a holdover, but it works for now. Thanks, Noah.