mirror of
https://github.com/golang/go
synced 2024-11-19 12:34:47 -07:00
exp/template: tweak behavior of booleans.
Russ suggested this technique, making the "and" and "or" functions handier. But it's hacky, and I can be talked out of it. R=dsymonds, rsc CC=golang-dev https://golang.org/cl/4698044
This commit is contained in:
parent
c3344d61bd
commit
469e333106
@ -199,7 +199,10 @@ the set but the Funcs methods can be used to add them.
|
|||||||
Predefined global functions are named as follows.
|
Predefined global functions are named as follows.
|
||||||
|
|
||||||
and
|
and
|
||||||
Returns the boolean AND of its arguments.
|
Returns the boolean AND of its arguments by returning the
|
||||||
|
first empty argument or the last argument, that is,
|
||||||
|
"and x y" behaves as "if x then y else x". All the
|
||||||
|
arguments are evaluated.
|
||||||
html
|
html
|
||||||
Returns the escaped HTML equivalent of the textual
|
Returns the escaped HTML equivalent of the textual
|
||||||
representation of its arguments.
|
representation of its arguments.
|
||||||
@ -213,7 +216,10 @@ Predefined global functions are named as follows.
|
|||||||
not
|
not
|
||||||
Returns the boolean negation of its single argument.
|
Returns the boolean negation of its single argument.
|
||||||
or
|
or
|
||||||
Returns the boolean OR of its arguments.
|
Returns the boolean OR of its arguments by returning the
|
||||||
|
first non-empty argument or the last argument, that is,
|
||||||
|
"or x y" behaves as "if x then x else y". All the
|
||||||
|
arguments are evaluated.
|
||||||
print
|
print
|
||||||
An alias for fmt.Sprint
|
An alias for fmt.Sprint
|
||||||
printf
|
printf
|
||||||
|
@ -289,7 +289,7 @@ func (s *state) evalCommand(dot reflect.Value, cmd *commandNode, final reflect.V
|
|||||||
case *stringNode:
|
case *stringNode:
|
||||||
return reflect.ValueOf(word.text)
|
return reflect.ValueOf(word.text)
|
||||||
}
|
}
|
||||||
s.errorf("can't handle command %q", firstWord)
|
s.errorf("can't evaluate command %q", firstWord)
|
||||||
panic("not reached")
|
panic("not reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,8 +280,8 @@ var execTests = []execTest{
|
|||||||
|
|
||||||
// Booleans
|
// Booleans
|
||||||
{"not", "{{not true}} {{not false}}", "false true", nil, true},
|
{"not", "{{not true}} {{not false}}", "false true", nil, true},
|
||||||
{"and", "{{and 0 0}} {{and 1 0}} {{and 0 1}} {{and 1 1}}", "false false false true", nil, true},
|
{"and", "{{and false 0}} {{and 1 0}} {{and 0 true}} {{and 1 1}}", "false 0 0 1", nil, true},
|
||||||
{"or", "{{or 0 0}} {{or 1 0}} {{or 0 1}} {{or 1 1}}", "false true true true", nil, true},
|
{"or", "{{or 0 0}} {{or 1 0}} {{or 0 true}} {{or 1 1}}", "0 1 true 1", nil, true},
|
||||||
{"boolean if", "{{if and true 1 `hi`}}TRUE{{else}}FALSE{{end}}", "TRUE", tVal, true},
|
{"boolean if", "{{if and true 1 `hi`}}TRUE{{else}}FALSE{{end}}", "TRUE", tVal, true},
|
||||||
{"boolean if not", "{{if and true 1 `hi` | not}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},
|
{"boolean if not", "{{if and true 1 `hi` | not}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},
|
||||||
|
|
||||||
@ -326,6 +326,10 @@ var execTests = []execTest{
|
|||||||
{"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
|
{"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
|
||||||
{"range empty interface", "{{range .Empty3}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
|
{"range empty interface", "{{range .Empty3}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
|
||||||
|
|
||||||
|
// Cute examples.
|
||||||
|
{"or as if true", `{{or .SI "slice is empty"}}`, "[3 4 5]", tVal, true},
|
||||||
|
{"or as if false", `{{or .SIEmpty "slice is empty"}}`, "slice is empty", tVal, true},
|
||||||
|
|
||||||
// Error handling.
|
// Error handling.
|
||||||
{"error method, error", "{{.EPERM true}}", "", tVal, false},
|
{"error method, error", "{{.EPERM true}}", "", tVal, false},
|
||||||
{"error method, no error", "{{.EPERM false}}", "false", tVal, true},
|
{"error method, no error", "{{.EPERM false}}", "false", tVal, true},
|
||||||
|
@ -122,22 +122,39 @@ func index(item interface{}, indices ...interface{}) (interface{}, os.Error) {
|
|||||||
|
|
||||||
// Boolean logic.
|
// Boolean logic.
|
||||||
|
|
||||||
// and returns the Boolean AND of its arguments.
|
func truth(a interface{}) bool {
|
||||||
func and(arg0 interface{}, args ...interface{}) (truth bool) {
|
t, _ := isTrue(reflect.ValueOf(a))
|
||||||
truth, _ = isTrue(reflect.ValueOf(arg0))
|
return t
|
||||||
for i := 0; truth && i < len(args); i++ {
|
|
||||||
truth, _ = isTrue(reflect.ValueOf(args[i]))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// or returns the Boolean OR of its arguments.
|
// and computes the Boolean AND of its arguments, returning
|
||||||
func or(arg0 interface{}, args ...interface{}) (truth bool) {
|
// the first false argument it encounters, or the last argument.
|
||||||
truth, _ = isTrue(reflect.ValueOf(arg0))
|
func and(arg0 interface{}, args ...interface{}) interface{} {
|
||||||
for i := 0; !truth && i < len(args); i++ {
|
if !truth(arg0) {
|
||||||
truth, _ = isTrue(reflect.ValueOf(args[i]))
|
return arg0
|
||||||
}
|
}
|
||||||
return
|
for i := range args {
|
||||||
|
arg0 = args[i]
|
||||||
|
if !truth(arg0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arg0
|
||||||
|
}
|
||||||
|
|
||||||
|
// or computes the Boolean OR of its arguments, returning
|
||||||
|
// the first true argument it encounters, or the last argument.
|
||||||
|
func or(arg0 interface{}, args ...interface{}) interface{} {
|
||||||
|
if truth(arg0) {
|
||||||
|
return arg0
|
||||||
|
}
|
||||||
|
for i := range args {
|
||||||
|
arg0 = args[i]
|
||||||
|
if truth(arg0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arg0
|
||||||
}
|
}
|
||||||
|
|
||||||
// not returns the Boolean negation of its argument.
|
// not returns the Boolean negation of its argument.
|
||||||
|
Loading…
Reference in New Issue
Block a user