mirror of
https://github.com/golang/go
synced 2024-11-19 12:04:43 -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.
|
||||
|
||||
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
|
||||
Returns the escaped HTML equivalent of the textual
|
||||
representation of its arguments.
|
||||
@ -213,7 +216,10 @@ Predefined global functions are named as follows.
|
||||
not
|
||||
Returns the boolean negation of its single argument.
|
||||
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
|
||||
An alias for fmt.Sprint
|
||||
printf
|
||||
|
@ -289,7 +289,7 @@ func (s *state) evalCommand(dot reflect.Value, cmd *commandNode, final reflect.V
|
||||
case *stringNode:
|
||||
return reflect.ValueOf(word.text)
|
||||
}
|
||||
s.errorf("can't handle command %q", firstWord)
|
||||
s.errorf("can't evaluate command %q", firstWord)
|
||||
panic("not reached")
|
||||
}
|
||||
|
||||
|
@ -280,8 +280,8 @@ var execTests = []execTest{
|
||||
|
||||
// Booleans
|
||||
{"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},
|
||||
{"or", "{{or 0 0}} {{or 1 0}} {{or 0 1}} {{or 1 1}}", "false true true 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 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 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 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 method, error", "{{.EPERM true}}", "", tVal, false},
|
||||
{"error method, no error", "{{.EPERM false}}", "false", tVal, true},
|
||||
|
@ -122,22 +122,39 @@ func index(item interface{}, indices ...interface{}) (interface{}, os.Error) {
|
||||
|
||||
// Boolean logic.
|
||||
|
||||
// and returns the Boolean AND of its arguments.
|
||||
func and(arg0 interface{}, args ...interface{}) (truth bool) {
|
||||
truth, _ = isTrue(reflect.ValueOf(arg0))
|
||||
for i := 0; truth && i < len(args); i++ {
|
||||
truth, _ = isTrue(reflect.ValueOf(args[i]))
|
||||
}
|
||||
return
|
||||
func truth(a interface{}) bool {
|
||||
t, _ := isTrue(reflect.ValueOf(a))
|
||||
return t
|
||||
}
|
||||
|
||||
// or returns the Boolean OR of its arguments.
|
||||
func or(arg0 interface{}, args ...interface{}) (truth bool) {
|
||||
truth, _ = isTrue(reflect.ValueOf(arg0))
|
||||
for i := 0; !truth && i < len(args); i++ {
|
||||
truth, _ = isTrue(reflect.ValueOf(args[i]))
|
||||
// and computes the Boolean AND of its arguments, returning
|
||||
// the first false argument it encounters, or the last argument.
|
||||
func and(arg0 interface{}, args ...interface{}) interface{} {
|
||||
if !truth(arg0) {
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user