views:

121

answers:

3

I have method to which I pass an object. In this method I check it's type and depending on the type I do something with it and return a Long. I have tried every which way I can think of to do this and I always get several compiler errors telling me it expects a certain object but gets another. Can someone please explain to me what I am doing wrong and guide me in the right direction? What I have tried thus far is below:

  override def getInteger(obj:Object) = {
    if (obj.isInstanceOf[Object]) null
    else if (obj.isInstanceOf[Number]) 
      (obj:Number).longValue()
    else if (obj.isInstanceOf[Boolean]) 
      if (obj:Boolean) 1 else 0
    else if (obj.isInstanceOf[String]) 
      if ((obj:String).length == 0 | (obj:String) == "null") 
        null
      else
          try {
            Long.parse(obj:String)
          } catch {
            case e: Exception => throw new ValueConverterException("value \"" + obj.toString() + "\" of type " + obj.getClass().getName() + " is not convertible to Long")        
          }
  }
+1  A: 

This code cries out for using a match:

obj match {
  case n: Number => n.longValue
  case b: Boolean => if (b) 1 else 0
  case s: String => if ((s eq null) || s.length == 0) null else {
            // try ... catch ... etc.
          }
  case o: Object => null
}

Followed my own advice from my comment to my original reply...

Randall Schulz
Of course, the problem with this is that with the Object case first, it will always match. It should be at to the end.
Randall Schulz
This will not compile as Boolean is not subclass of Object.
missingfaktor
@Rahul G: That would be undiagnosed in the original but manifest in this case, a sign that using Scala's features help you expunge type errors.
Randall Schulz
+1  A: 

This might be a start:

def getInteger (o : Any) : Long = o match {
     case (o: Boolean) => if (o) 1 else 0       
     case (l: Long) => l                        
     case (s: String) => java.lang.Long.parseLong (s)   
     case _ => 0L 
}  

(I don't have something to override, and skipped the try/catch for brevity)

user unknown
+10  A: 

Pattern matching would make it much more nicer.

def getInteger(obj: Any) = obj match {
  case n: Number => n.longValue
  case b: Boolean => if(b) 1 else 0
  case s: String if s.length != 0 && s != "null" => s.toLong
  case _ => null
}
missingfaktor
this worked out perfectly, with the exception that in the boolean case, i got a compiler error saying a long was expected. I took care of this by modifying it to `if(b) 1.longValue else 0.longValue`
Russ Bradberry
It's kinda crazy there is no implicit from int to long. It's ALWAYS safe to do that.
davetron5000
@Russ: Or you could write `if(b) 1L else 0L`.
missingfaktor
Great!, The more and more I use Scala, I am beginning to like it.
Russ Bradberry