From bddc74eac884c3af50158bbf8d9017a2fdd0e82e Mon Sep 17 00:00:00 2001 From: Back Yu Date: Sat, 19 Jan 2019 12:12:09 +0800 Subject: [PATCH 1/3] Add support for method of map. --- runtime.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/runtime.go b/runtime.go index d27d8bacf..a5e3b7320 100644 --- a/runtime.go +++ b/runtime.go @@ -96,6 +96,14 @@ func getFunc(val interface{}, i interface{}) (interface{}, bool) { if value.IsValid() && value.CanInterface() { return value.Interface(), true } + // A map may have method too. + if v.NumMethod() > 0 { + name := reflect.ValueOf(i).String() + method := v.MethodByName(name) + if method.IsValid() && method.CanInterface() { + return method.Interface(), true + } + } case reflect.Struct: name := reflect.ValueOf(i).String() method := v.MethodByName(name) From 47bbccba33cd5fe056967222a4811d68e5a152c8 Mon Sep 17 00:00:00 2001 From: Back Yu Date: Sat, 19 Jan 2019 12:24:46 +0800 Subject: [PATCH 2/3] Improve the reflect of getFunc(...) --- runtime.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/runtime.go b/runtime.go index a5e3b7320..51954d52d 100644 --- a/runtime.go +++ b/runtime.go @@ -83,7 +83,7 @@ func extract(val interface{}, i interface{}) (interface{}, bool) { return nil, false } -func getFunc(val interface{}, i interface{}) (interface{}, bool) { +func getFunc(val interface{}, name string) (interface{}, bool) { v := reflect.ValueOf(val) d := v if v.Kind() == reflect.Ptr { @@ -92,20 +92,18 @@ func getFunc(val interface{}, i interface{}) (interface{}, bool) { switch d.Kind() { case reflect.Map: - value := d.MapIndex(reflect.ValueOf(i)) + value := d.MapIndex(reflect.ValueOf(name)) if value.IsValid() && value.CanInterface() { return value.Interface(), true } // A map may have method too. if v.NumMethod() > 0 { - name := reflect.ValueOf(i).String() method := v.MethodByName(name) if method.IsValid() && method.CanInterface() { return method.Interface(), true } } case reflect.Struct: - name := reflect.ValueOf(i).String() method := v.MethodByName(name) if method.IsValid() && method.CanInterface() { return method.Interface(), true From 20aeaab3e07093d52d5d4a94cf6407f5409bdd77 Mon Sep 17 00:00:00 2001 From: Back Yu Date: Sat, 19 Jan 2019 16:13:20 +0800 Subject: [PATCH 3/3] Add tests for support method of map. --- eval_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/eval_test.go b/eval_test.go index 308ddd4f4..2abd0fe36 100644 --- a/eval_test.go +++ b/eval_test.go @@ -21,6 +21,22 @@ type evalErrorTest struct { err string } +type evalParams map[string]interface{} + +func (p evalParams) Max(a, b float64) float64 { + if a < b { + return b + } + return a +} + +func (p evalParams) Min(a, b float64) float64 { + if a < b { + return a + } + return b +} + var evalTests = []evalTest{ { "foo", @@ -339,6 +355,16 @@ var evalTests = []evalTest{ map[string]interface{}{"foo": func(in string) string { return "hello " + in }}, "hello world", }, + { + "Max(a, b)", + evalParams{"a": 1.23, "b": 3.21}, + 3.21, + }, + { + "Min(a, b)", + evalParams{"a": 1.23, "b": 3.21}, + 1.23, + }, } var evalErrorTests = []evalErrorTest{