In Freemarker, I have a Map that contains null as a key.
How can I reach that entry?
As far as I know, Freemarker doesn't know the concept of null, so there's nothing like map[null], is there?
There isn't, also map[key] only works with string keys (in 2.3.x at least). Try map?api.get(null) (where null is really just a variable that doesn't exist).
Related
I am new to Drools, we are trying to create basic validation rules like a NULL check, etc. using the Drools n Scala framework.
I have a source file which has 200 attributes, need to apply NULL-check rule on all these attributes,
is there any easy way to do this? or do I need to create 200 rules for each attribute?
Thanks in advance.
Assuming you have a POJO ("plain old java object", getters/setters and some private variables to hold values) or modern java Records (effectively the same thing), then the answer is no: you need separate rules. For this scenario, the only way to check that field "name" is null is to actually assert against that field like this:
rule "example - name is null"
when
ExampleObject( name == null )
then
System.out.println("Name is null.");
end
However there exist other data structures -- for example, Map and its sibling types -- where you can reference the fields by name. In this case you could theoretically iterate through all of the field names and find the one whose value is empty.
So, for example, Map has a keySet() method which returns a set of fields -- you could iterate through this keyset and for each key check that there is a non-null value present in the map.
rule "example with map"
when
$map: Map()
$keys: Set() from $map.keySet()
$key: String() from $keys
String( this == null ) from $map.get($key)
// or this might work, not sure if the "this" keyword allows this syntax:
// Map( this[$key] == null ) from $map
then
System.out.println($key + " is missing/null");
end
This would require converting your Java object into a Map before passing into the rules.
However I DO NOT RECOMMEND this approach. Maps are extremely un-performant in rules because of how they serialize/deserialize. You will use a ton of unnecessary heap when firing them. If you look at how a HashMap serializes, for example, by peeking at its source code you'll see that it actually contains a bunch of "child" data structures like entryset and keyset and things like that. When using "new", those child structures are only initialized if and when you need them; but when serializing/deserializing, they're created immediately even if you don't need them.
Another solution would be to use Java reflection to get the list of declared field names, and then iterate through those names using reflection to get the value out for that field. In your place I'd do this in Java (reflection is problematic enough without trying to do it in Drools) and then if necessary invoke such a utility function from Drools.
Liskov substitution principle:
B is a subtype of A iff anything one can do with A one can do with B.
So why is Null a subtype of all classes in Scala even though by the above definition it isn't a subtype of any class? Couldn't Null have been defined as implementing all possible methods, each returning null? What are the reasons Null was defined the way it is in Scala?
Null is pretty much unavoidable on the JVM. References can be null. Scala can't stop that.
All Scala did was include Java's null into the unified type system. It exists for Java interop, nothing more. Null was wrong in Java, and it's also wrong in Scala.
Yes, null references are the ultimate LSP violation. No, there's no way to fix that. Evaluating method invocations on null to null instead of to throwing NullPointerException wouldn't be any more or less correct, just equally nonsensical.
There's really nothing interesting to see here. Wrap anything nullable in Option(...), forget about this dark pit of incorrectness, and move on.
Couldn't Null have been defined as implementing all possible methods, each returning null?
No. 1. Methods returning primitive types can't return null; 2. the only reason Scala has null is because JVM has it; and the JVM null doesn't behave this way. This would require basically adding an if before every method call unless the compiler can prove the receiver isn't null, which it normally can't.
When I use Maps.uniqueIndex with a List that contains a duplicate value,
java.lang.IllegalArgumentException: duplicate key: 836
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:115)
is thrown.
I find this inconvenient. I suppose it does make some sense, but if a unique collection is required for the function to work correctly, why does it accept an Iterable as an argument in stead of a Set?
List<GroupVO> groups = groupDao.getAll(groupIds);
Map<String,GroupVO> groupMap groupMap = Maps.uniqueIndex(groups, new Function<GroupVO,String>() {
public String apply(GroupVO vo) {
return vo.getId().toString();
}});
It is simply not possible to have multiple values for one key in a plain Map, thus uniqueIndex cannot do anything else.
It accepts Iterable because accepting only Set would restrict its possible usages and still not solve the problem. Not the values in the given Iterable need to be unique, but the result of applying the given function on each of them.
If you need multiple values per key, you can simply use Multimaps.index, which does the same but returns a Multimap (which can contain an arbitrary number of values per key).
I think what confuses people here (including me when I'm not paying attention) is that typical Maps (e.g. HashMap) will quietly accept writing a new value to a key; the new value replaces the old one, so if the values are also the same, it's a silent no-op. The Immutable*.Builder family throws under the same circumstances.
I want to search for a field that has any values, essentially SQL's IS NOT NULL. I tried
with :fieldA
thinking it means 'with value'. However it does not work. What's the Sunspot way to specify IS NOT NULL?
I found out that I need
without :fieldA, nil
It's kind of obvious once I know it.
How do I test and see if a variable is set in Scala. In PHP you would use isset()
I am looking for a way to see if a key is set in an array.
First, Array in Scala does not have keys. They have indices, and all indices have values in them. See the edit below about how those values might be initialized, though.
You probably mean Map, which has keys. You can check whether a key is present (and, therefore, a value) by using isDefinedAt or contains:
map isDefinedAt key
map contains key
There's no practical difference between the two. Now, you see in the edit that Scala favors the use of Option, and there's just such a method when dealing with maps. If you do this:
map get key
You'll receive an Option back, which will be None if the key (and, therefore, the value) is not present.
EDIT
This is the original answer. I've noticed now that the question is not exactly about this.
As a practical matter, all fields on the JVM are pre-initialized by the JVM itself, which zeroes it. In practice, all reference fields end up pointing to null, booleans are initialized with false and all other primitives are initialized with their version of zero.
There's no such thing in Scala as an "undefined" field -- you cannot even write such a thing. You can write var x: Type = _, but that simply results in the JVM initialization value. You can use null to stand for uninitialized where it makes sense, but idiomatic Scala code tries to avoid doing so.
The usual way of indicating the possibility that a value is not present is using Option. If you have a value, then you get Some(value). If you don't, you get None. See other Stack Overflow questions about various ways of using Option, since you don't use it like variable.isDefined in idiomatic code either (though that works).
Finally, note that idiomatic Scala code don't use var much, preferring val. That means you won't set things, but, instead, produce a new copy of the thing with that value set to something else.
PHP and Scala are so different that there is no direct equivalent. First of all Scala promotes immutable variables (final in Java world) so typically we strive for variables that are always set.
You can check for null:
var person: Person = null
//...
if(person == null) {//not set
//...
}
person = new Person()
if(person == null) {//set
//...
}
But it is a poor practice. The most idiomatic way would be to use Option:
var person: Option[Person] = None
//...
if(person.isDefined) {//not set
//...
}
person = Some(new Person())
if(person.isDefined) {//set
//...
}
Again, using isDefined isn't the most idiomatic ways. Consider map and pattern matching.