Skip to content
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

Cannot use map[string]interface {} as argument (type main.Env) to call dump #694

Open
vmihailenco opened this issue Aug 9, 2024 · 5 comments

Comments

@vmihailenco
Copy link

vmihailenco commented Aug 9, 2024

The following program incorrectly assumes that the type of $env is map[string]any, although args[0] holds Env:

package main

import (
	"fmt"
	"time"

	"github.com/davecgh/go-spew/spew"
	"github.com/expr-lang/expr"
)

type Env struct {
}

func (Env) Dump(args ...any) (any, error) {
	spew.Dump(args)
	return nil, nil
}

func main() {
	code := `dump($env)`

	env := Env{}
	program, err := expr.Compile(code,
		expr.Function("dump", env.Dump, new(func(Env) any)),
		//expr.Function("dump", env.Dump, new(func(any) any)),
		expr.Env(env)) // Pass the struct as an environment.
	if err != nil {
		panic(err)
	}

	output, err := expr.Run(program, env)
	if err != nil {
		panic(err)
	}

	fmt.Print(output)
}

Changing expr.Function("dump", env.Dump, new(func(Env) any)) to expr.Function("dump", env.Dump, new(func(any) any)) will allow to compile the program and inspect the type of the arg.

@antonmedv
Copy link
Member

Type of $env is always a map. This is internal agreement of how env works. From expr perspective it is not important if env is struct or a map.

@vmihailenco
Copy link
Author

Type of $env is always a map.

When I pass $env as an arg to a function I get main.Env, not a map.

@antonmedv
Copy link
Member

Yes, in golang. But Expr assumes it is a map. As you can use $env[“var”] and $env.var on any env.

@antonmedv
Copy link
Member

But I think we can improve our type checker to also allow this kind of usages.

Let me look into how to implement it.

@antonmedv
Copy link
Member

antonmedv commented Aug 10, 2024

Note: there is no need to only use methods defence on environment. You can use any functions to defined anywhere.

expr.Function("dump", func(params ...any) (any, error) { return spew.Dump(params[0]) }, spew.Dump)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants