velocity: tri-state Boolean property check
How do I fork three different cases depending on all the three states that Boolean property may have? Java code for this looks simple:
public class Foo {
public Boolean getBool() { return null /* this would be dynamic in RL */; }
}
// somewhere in the servlet code:
if (foo.getBool() == null) {
resp.getWriter().print("not yet set");
} else if (foo.getBool()) {
resp.getWriter().print("set to TRUE");
} else {
resp.getWriter().print("set to FALSE");
}
Velocity seems to epically fail here, as the spec has no null literal and boolean/not-null equality checks are somewhat fungible for the sake of simplicity. Of course, there're two solutions to avoid this dilemma (see below), but is there some straightforward/cleaner way?
just add an extra getter to the Foo class, like so:
boolean isBoolSet() {return getBool() != null; }
and the VTL code would then be:
开发者_Go百科#if(!$foo.boolSet)
not yet set
#else
#if($foo.bool)
set to TRUE
#else
set to FALSE
#end
#end
fetch some null value, like so,
Object getTheNull() {return null; }
and the VTL then would look like:
#if($foo.bool == $foo.theNull)
not yet set
#else
#if($foo.bool)
set to TRUE
#else
set to FALSE
#end
#end
If you use a modern version of Velocity, you can just use $null or $anyReferenceThatHasNoValue. You can also use #elseif to simplify things:
#if($foo.bool == $null)
not yet set
#elseif($foo.bool)
set to TRUE
#else
set to FALSE
#end
But seriously, this is a hack any way you slice it. You should be using an enum.
Any time I've tried to shoehorn something where it didn't fit, I've always ended up regretting not just moving to the more appropriate state in the first place.
Give yourself an enum, then you can explicitly say that it's NOT_READY. Explicit is good. A few extra lines of code over comments is awesome.
Another example of this is--if you ever wonder about creating a new class or putting more code in an existing class, you probably need 2 or 3 new classes.
Just go ahead and do it.
!$foo.bool && $foo.bool != false
is equivalent to
$foo.bool == $null (in Velocity 1.6 onwards)
I guess it's all just about late night coding and somewhat stale/minimalistic Velocity User Guide...
Why dont you initialise your Boolean inside the constructor? That way it will never be null
精彩评论