d5/tengo

stdlib.fmt.println not behaving like fmt.Println

abck opened this issue · 3 comments

abck commented

Hello,

just want to ask if the behavior of stdlib.fmt.println is correct.

I was expecting it to behave like the go's fmt.Println.

Minimal example:

func main() {
	script := tengo.NewScript([]byte(`fmt := import("fmt")
fmt.println(a, a)`))
	_ = script.Add("a", 1)

	moduleMap := stdlib.GetModuleMap(stdlib.AllModuleNames()...)
	script.SetImports(moduleMap)

	compiled, err := script.RunContext(context.Background())
	if err != nil {
		panic(err)
	}
	a := compiled.Get("a")
	fmt.Println(a, a)
}

Output:

11 
1 1

1st line is the output of tengo's fmt.println
2nd line is the output of go's fmt.Println

If this is not intended, it can be fixed by changing fmtPrintln in stdlib/fmt.go to

func fmtPrintln(args ...tengo.Object) (ret tengo.Object, err error) {
	printArgs, err := getPrintArgs(args...)
	if err != nil {
		return nil, err
	}
	_, _ = fmt.Println(printArgs...)
	return nil, nil
}

@d5 will you accept such patch?

d5 commented

This is the current code:

func fmtPrintln(args ...tengo.Object) (ret tengo.Object, err error) {
	printArgs, err := getPrintArgs(args...)
	if err != nil {
		return nil, err
	}
	printArgs = append(printArgs, "\n")
	_, _ = fmt.Print(printArgs...)
	return nil, nil
}

Honestly, I don't remember why I specifically used fmt.Print. It's been a while. @geseq any ideas?

geseq commented

Tbh I can’t recall either but looking at the code the only reason I can think of is to avoid printing spaces between the operands.

that said, I would be happy for this to behave like standard library.