Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

EL Relational Operators

 
Narendra Dhande
Ranch Hand
Posts: 951
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I tested following EL Expressions



The output of the above is



The question is how the comparision is made on the boolean operands. From the above output it look like that they are corec to String and then compared lexically. If this is the case then how the expression at line 7 return true. Also in expressions 1,2,3 none of the operand is String. Is there is specific rules in EL.

${false eq 0} (0 without quotes giving me ELException )

Please Clarify.

Thanks
 
Christophe Verré
Sheriff
Posts: 14691
16
Eclipse IDE Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
== or eq will coerce both value to Boolean if one of them is Boolean.
So ${false eq "0"} will result in "0" being converted to a Boolean, whose value is false. Therefore, "false eq false" returns true.
The String coercion actually happens when neither of the values are Boolean.

The spec is very handy.
Check JSP.2.3.5.5 Relational Operators
 
Narendra Dhande
Ranch Hand
Posts: 951
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Thanks for the reply. I have gone through this specification, but I have little bit confusions while understanding the rules.

The spec also stated that if one of the operand is String, then both Corec to String. Which rule apply first.

In the line 1,2,3 both the operand of type Boolean constant. I think the Boolean does not comparable, then it should be error, if they are not corec to String.

In the following example, you can see that if either operand in numeric constant, then the numeric comparision is made, though the other operand is String. So, is there is any rule (precedence) when the value is corec to String or other type.



The output is



Please clarify

Thanks
 
Charles Lyons
Author
Ranch Hand
Posts: 836
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The spec also stated that if one of the operand is String, then both Corec to String. Which rule apply first.

The rules should always be applied in the order they are given in the spec. So the equality test will perform these in order, executing whichever case it matches first:
  • A==B (reference comparison)
  • Null checks - returns false if either object is null
  • If either are BigDecimal, coerce to BD and A.equals(B)
  • If either are Float or Double, coerce both to Double and apply
  • BigInteger tests are next
  • Byte, Short... Long test are done here
  • If either are Boolean (or boolean primitives), coerce to Boolean and apply
  • If either are Strings, coerce both to String and compare lexically
  • ...

  • So:

    In the first we have two strings, so we'll compare lexically - and they obviously aren't equal. In the second we have two strings, and again we are testing lexically (although now for > and not for ==), and by the rules of String.compareTo(), we would expect "1" to be 'larger' than "01", as "1" would come after "01" in a dictionary. For line 17 however, one of the terms is a number - and by the list of rules above, numbers are done before strings... so convert "01" to the number 1 and do 1 > 1, which gets the answer false.

    In the following example, you can see that if either operand in numeric constant, then the numeric comparision is made, though the other operand is String. So, is there is any rule (precedence) when the value is corec to String or other type.

    This is what should happen, because, loosely speaking, numbers are done before strings. I think your second example shows this, but you didn't include the result for line 12, which I think should be true just like line 13. These lines are in fact equivalent, and are both converted to Integers before doing the comparison:


    I hope that helps.
     
    Christophe Verré
    Sheriff
    Posts: 14691
    16
    Eclipse IDE Ubuntu VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Sorry Narendra, I was logged out.
    As Charles said, the order of coercion stated in the spec is important.
    For "==" or "eq" the Boolean coercion will be applied before the String one.
     
    Vidya Sethuraman
    Ranch Hand
    Posts: 45
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi,

    I tried out the example
    1: ${true < false} <br>
    2: ${true == false } <br>
    3: ${true > false} <br>
    4: ${true > "false"} <br>
    5: ${false eq "false"} <br>
    6: ${false < "naren"} <br>
    7: ${false eq "0"} <br>
    but I'm getting the following error:
    javax.servlet.jsp.el.ELException: Attempt to apply operator "<" to arguments of type "java.lang.Boolean" and "java.lang.Boolean"

    Thanks!
     
    Narendra Dhande
    Ranch Hand
    Posts: 951
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Charles, Satou. Now it is clear.

    Thanks Vidya, I am expecting the output as is yours, as the boolean can not comparable. But I am getting the output like true or false. I am testing it on the Sun Java Application server 8.1. On which container you tested the above lines ?

    Thanks
     
    Christophe Verré
    Sheriff
    Posts: 14691
    16
    Eclipse IDE Ubuntu VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    No error in Tomcat 5.5 either. That's weird.
    Tomcat is using commons-el.jar to evalute the expressions but.... humm... strange.
     
    Narendra Dhande
    Ranch Hand
    Posts: 951
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi,

    I also tested on Tomcat 5.5.7. No errors/exceptions

    Thanks
     
    Promod kumar
    Ranch Hand
    Posts: 90
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    true < false

    I am still not clear how it is evaluated. I pasted the section of the spec below. The above case is not covered by the spec. So this should be undefined per the spec. Am I right. When I try this on Tomcat I get false. Looks like true and false are converted to Strings and compared but the spec does not address this scenario. Let me know if I am missing anything. I don't think I have a good handle on this.

    Also I don't understand the first rule below. Can someone explain.

    JSP.2.3.5.6 A {<,>,<=,>=,lt,gt,le,ge} B
    � If A==B, if operator is <=, le, >=, or ge return true. Otherwise return false
    � If A is null or B is null, return false
    � If A or B is BigDecimal, coerce both A and B to BigDecimal and use the return
    value of A.compareTo( B ).
    � If A or B is Float or Double coerce both A and B to Double apply operator
    � If A or B is BigInteger, coerce both A and B to BigInteger and use the return
    value of A.compareTo( B ).
    � If A or B is Byte, Short, Character, Integer, or Long coerce both A and B to
    Long and apply operator
    � If A or B is String coerce both A and B to String, compare lexically
    � If A is Comparable, then:
    If A.compareTo (B) throws exception, error.
    Otherwise use result of A.compareTo(B)
    � If B is Comparable, then:
    If B.compareTo (A) throws exception, error.
    Otherwise use result of B.compareTo(A)
    � Otherwise, error
     
    Promod kumar
    Ranch Hand
    Posts: 90
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Here is a good reference if you are banging your head against the wall about operators and corecion etc. I still don't have a reply for my earlier post.

    http://commons.apache.org/el/apidocs/org/apache/commons/el/Coercions.html
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic