Closed martinda closed 9 years ago
StringTemplate 4 defines the result of <if(x)>
for all values of x
.
x |
<if(x)>foo<else>bar<endif> |
---|---|
null or not defined |
bar |
true (Boolean in Java) |
foo |
false (Boolean in Java) |
bar |
Instance of Collection<E> or Map<K, V> , where size() > 0 |
foo |
Instance of Collection<E> or Map<K, V> , where size() == 0 |
bar |
Instance of Iterable<T> , where x.iterator().hasNext() |
foo |
Instance of Iterable<T> , where !x.iterator().hasNext() |
bar |
Instance of Iterator<T> , where x.hasNext() |
foo |
Instance of Iterator<T> , where !x.hasNext() |
bar |
Otherwise | foo |
Since there are no values for which <if(x)>
is an error, changing the behavior of this construct runs a very high risk of breaking the behavior of applications that already use it. Can you give a more specific example of the inputs you have and the outputs you want? There may be another way to approach your specific case that fits within the current behavior.
What about the case where x is a number and has a value of zero or x is a string and has a length of zero?
On Sun, Dec 14, 2014 at 10:41 PM, Sam Harwell notifications@github.com wrote:
StringTemplate 4 defines the result of <if(x)> for all values of x. x <if(x)>foo
bar null or not defined bar true (Boolean in Java) foo false (Boolean in Java) bar Instance of Collection or Map<K, V>, where size() > 0 foo Instance of Collection or Map<K, V>, where size() == 0 bar Instance of Iterable , where x.iterator().hasNext() foo Instance of Iterable , where !x.iterator().hasNext() bar Instance of Iterator , where x.hasNext() foo Instance of Iterator , where !x.hasNext() bar Otherwise foo Since there are no values for which <if(x)> is an error, changing the behavior of this construct runs a very high risk of breaking the behavior of applications that already use it. Can you give a more specific example of the inputs you have and the outputs you want? There may be another way to approach your specific case that fits within the current behavior.
Reply to this email directly or view it on GitHub https://github.com/antlr/stringtemplate4/issues/92#issuecomment-66946523 .
Both of those cases fall into the "Otherwise" category at the end of the table.
If you want zero and the empty string to be treated as false for a particular expression, you can use something like this:
zeroOrEmptyAsFalse ::= [
"": [],
"0": [],
default: key
]
example(value) ::= "<if(zeroOrEmptyAsFalse.(value))>foo<else>bar<endif>"
Note that the above is supported starting with StringTemplate 4.0.7 (see #33). Prior to that, you would need to use the following definition for zeroOrEmptyAsFalse
:
zeroOrEmptyAsFalse ::= [
"": false,
"0": false,
default: key
]
ah. i wondered if we already handled len(list)==0 etc... Yeah, testing 0 as false would break the semantics.
The if-attribute conditional could be enhanced to convert certain data type values to boolean. For example, python and groovy convert empty containers (empty lists, empty hash tables, empty maps) to false, the empty string to false and number zero to false (non-zero would be true, positive or negative). It looks as if nulls are already converted to false. I think this would be useful, as it would reduce the business logic when assigning template values. Right now, zeros, empty strings and empty containers have to be explicitely converted to false or null before being passed to the template.