expr
expr copied to clipboard
[Feature Request] Allow dots in injected Expr function names
We'd like to inject effectively an entire package into our Expr environment with a dozen or so methods. We were hoping to be able to effectively treat it like Go's package syntax and do something like:
expr.Function("pkg.NewThing", func(p ...any) (any, error) { }
But pkg.
seems disallowed as the Compile step throws an error like:
unknown name pkg (1:9)
| let x = pkg.NewThing([1, 2, 3]); x.String()
| ........^
What about adding a variable containing a struct with all needed methods?
type Pkg struct{}
func (p Pkg) NewThing(a, b int) int {
return a + b
}
func main() {
env := map[string]interface{}{
"pkg": Pkg{},
}
program, err := expr.Compile(`pkg.NewThing(1, 2)`, expr.Env(env))
}
I was hoping to avoid touching the passed in Env
where sometimes we're passing around concrete types and not just a map[string]any
, but that would work.
I see. This is actually a good point. in case you’re passing extract as it’s not possible always to add additional methods
Let me think for an api of declaring namespaces four functions
I think the method that @antonmedv suggested is elegant & straightforward. I use the same. @polds , the expr.compile/run functions could be fronted by another function which (as needed) wraps the incoming object (based on its type) and adds requisite functions (in your case a library) to a [say] wrapper.utils member which could be an array/map.
Yes, this is a good suggestion. Even if you are using a struct as an environment, it is possible to embed the struct in another struct.
type Wrapper struct {
MyEnv
Pkg Pkg `expr:"pkg"`
}
type Pkg struct{}
func (p Pkg) NewThing(a, b int) int {
return a + b
}
func main() {
program, err := expr.Compile(`pkg.NewThing(1, 2)`, expr.Env(Wrapper{}))
}