tengo icon indicating copy to clipboard operation
tengo copied to clipboard

Object Types documentation example out of date?

Open wader opened this issue 4 years ago • 1 comments

Hello! I'm reading https://github.com/d5/tengo/blob/master/docs/objects.md and tried the StringArray example but could not get it working without some changes. Not sure it the example is out of date or of I'm doing something wrong.

Without these changes I get Runtime Error: invalid operation: string-array + string.

Things I changed:

  • Added s.SetImports(stdlib.GetModuleMap("fmt"))/fmt := import("fmt") and changed print(..) tofmt.println
  • Changed func (o *StringArray) BinaryOp(...) to take a string instead of a StringArray as RHS.
package main

import (
	"strings"

	"github.com/d5/tengo/v2"
	"github.com/d5/tengo/v2/stdlib"
	"github.com/d5/tengo/v2/token"
)

type StringArray struct {
	tengo.ObjectImpl
	Value []string
}

func (o *StringArray) String() string {
	return strings.Join(o.Value, ", ")
}

func (o *StringArray) BinaryOp(op token.Token, rhs tengo.Object) (tengo.Object, error) {
	if rhs, ok := rhs.(*tengo.String); ok {
		switch op {
		case token.Add:
			if len(rhs.Value) == 0 {
				return o, nil
			}
			return &StringArray{Value: append(o.Value, rhs.Value)}, nil
		}
	}

	return nil, tengo.ErrInvalidOperator
}

func (o *StringArray) IsFalsy() bool {
	return len(o.Value) == 0
}

func (o *StringArray) Equals(x tengo.Object) bool {
	if x, ok := x.(*StringArray); ok {
		if len(o.Value) != len(x.Value) {
			return false
		}

		for i, v := range o.Value {
			if v != x.Value[i] {
				return false
			}
		}

		return true
	}

	return false
}

func (o *StringArray) Copy() tengo.Object {
	return &StringArray{
		Value: append([]string{}, o.Value...),
	}
}

func (o *StringArray) TypeName() string {
	return "string-array"
}

func main() {

	// script that uses 'my_list'
	s := tengo.NewScript([]byte(`
fmt := import("fmt")
fmt.println(my_list + "three")
`))

	s.SetImports(stdlib.GetModuleMap("fmt"))

	myList := &StringArray{Value: []string{"one", "two"}}
	s.Add("my_list", myList) // add StringArray value 'my_list'
	s.Run()                  // prints "one, two, three"
}

wader avatar Dec 27 '20 18:12 wader

(o *StringArray) BinaryOp doesn't allow to add a string to StringArray, while the example script does exactly that with my_list + "three". The code used for (o *StringArray) BinaryOp would allow a script to execute my_list + my_list only. That's the issue: The StringArray implementation doesn't match the example given for using it in a script.

I would rather change the (o *StringArray) BinaryOp code to allow adding a StringArray to a StringArray and adding a string to a StringArray.

avpaderno avatar Apr 03 '21 10:04 avpaderno