open2b/scriggo

Invalid behavior when calling variadic methods

jopbrown opened this issue · 2 comments

Here is a go package chain with chain call API

package chain

func Echo(name string, args ...string) {
	for _, arg := range args {
		println(name, arg)
	}
}

type Chain struct {
	name string
}

func New() *Chain {
	return &Chain{}
}

func (c *Chain) SetName(name string) *Chain {
	return &Chain{name: name}
}

func (c *Chain) Echo(args ...string) *Chain {
	for _, arg := range args {
		println(c.name, arg)
	}

	return c
}

Import into scriggo

IMPORT chain

Execute code

package main

import "chain"

func main() {
	println("echo without chain")
	chain.Echo("name1")               // print nothing
	chain.Echo("name2", "aaa", "bbb") // print 2 lines

	println()

	println("echo with chain")
	chain.New().SetName("name3").Echo()             // print nothing
	chain.New().SetName("name4").Echo("aaa", "bbb") // print 2 lines
}

Scriggo output

echo without chain
name2 aaa
name2 bbb

echo with chain
name3 name3
name4 aaa
name4 bbb
name4 bbb

gc output

echo without chain
name2 aaa
name2 bbb

echo with chain
name4 aaa
name4 bbb

Thanks @jopbrown for reporting this issue, we're investigating on it.

The invalid behaviour can be reduced to:

// Scriggo code.
package main

import "chain"

func main() {
	t := chain.T{}
	t.M("a")
}
// Native code.
package chain

import "fmt"

type T struct{}

func (c T) M(args ...string) {
	fmt.Printf("%#v (len %d)\n", args, len(args))
}

which should print:

[]string{"a"} (len 1)

but instead it prints:

[]string{"a", ""} (len 2)