]> Cypherpunks repositories - gostls13.git/commitdiff
exp/template: allow an empty interface value to be the target of range, etc.
authorRob Pike <r@golang.org>
Wed, 6 Jul 2011 06:40:46 +0000 (16:40 +1000)
committerRob Pike <r@golang.org>
Wed, 6 Jul 2011 06:40:46 +0000 (16:40 +1000)
We extract the concrete value inside.

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/4677041

src/pkg/exp/template/exec.go
src/pkg/exp/template/exec_test.go

index 87219e5e6c237ff5e3b70b4c4209ebb2ba963556..b8cfb5480677bd4f94e21d5fe45fcc4a87e00754 100644 (file)
@@ -183,6 +183,10 @@ func (s *state) evalPipeline(data reflect.Value, pipe []*commandNode) reflect.Va
        value := reflect.Value{}
        for _, cmd := range pipe {
                value = s.evalCommand(data, cmd, value) // previous value is this one's final arg.
+               // If the object has type interface{}, dig down one level to the thing inside.
+               if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 {
+                       value = reflect.ValueOf(value.Interface()) // lovely!
+               }
        }
        return value
 }
index 534690a6a3ee306cd4c5a27b6dc4887f329db40d..5be82dd6eff0be807a02615920fb0bad6e1e229d 100644 (file)
@@ -31,6 +31,8 @@ type T struct {
        MSI      map[string]int
        MSIone   map[string]int // one element, for deterministic output
        MSIEmpty map[string]int
+       // Empty interface; used to see if we can dig inside one.
+       EmptyInterface interface{}
 }
 
 // Simple methods with and without arguments.
@@ -79,14 +81,15 @@ type U struct {
 }
 
 var tVal = &T{
-       I:      17,
-       U16:    16,
-       X:      "x",
-       U:      &U{"v"},
-       SI:     []int{3, 4, 5},
-       SB:     []bool{true, false},
-       MSI:    map[string]int{"one": 1, "two": 2, "three": 3},
-       MSIone: map[string]int{"one": 1},
+       I:              17,
+       U16:            16,
+       X:              "x",
+       U:              &U{"v"},
+       SI:             []int{3, 4, 5},
+       SB:             []bool{true, false},
+       MSI:            map[string]int{"one": 1, "two": 2, "three": 3},
+       MSIone:         map[string]int{"one": 1},
+       EmptyInterface: []int{7, 8},
 }
 
 type execTest struct {
@@ -187,6 +190,7 @@ var execTests = []execTest{
        {"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true},
        {"range map else", "{{range .MSI | .MSort}}-{{.}}-{{else}}EMPTY{{end}}", "-one--three--two-", tVal, true},
        {"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+       {"range empty interface", "{{range .EmptyInterface}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
        // Error handling.
        {"error method, error", "{{.EPERM true}}", "", tVal, false},
        {"error method, no error", "{{.EPERM false}}", "false", tVal, true},