d5 / tengo

A fast script language for Go
https://tengolang.com
MIT License
3.52k stars 304 forks source link

stdlib.fmt.println not behaving like fmt.Println #352

Open abck opened 2 years ago

abck commented 2 years ago

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
}
misiek08 commented 2 years ago

@d5 will you accept such patch?

d5 commented 2 years ago

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 2 years ago

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.