4

How do I define the method return type in the following case:

working code

def deleteInstance(model: String, uid: Long) =  model match {
    case "menu" => Model.all(classOf[Menu]).filter("uid", uid).get().delete()
    case "articles" => Model.all(classOf[Articles]).filter("uid", uid).get().delete()
    case "news" => Model.all(classOf[News]).filter("uid", uid).get().delete()
    case "image" =>Model.all(classOf[Image]).filter("uid", uid).get().delete()
    case "files" =>Model.all(classOf[Files]).filter("uid", uid).get().delete()
    case _ => false
  }

non-working code:

class ModelManager{
  def getModel(model: String) = {
    model match{
      case "menu" => classOf[Menu]
      case "articles" => classOf[Articles]
      case _ => false
    }

  def deleteInstance(model:String, uid: Long) = {
    Model.all(getModel(model)).filter("uid", uid).get().delete()
  }    
 }
} 

Error raised is:

recursive method getModel needs result type

Landei
  • 54,104
  • 13
  • 100
  • 195
user816472
  • 49
  • 3
  • It's great, you use Siena + Scala and this is one thing I wanted to do asap. I'm main developer of Siena and I also intend to provide a Siena4Scala which would use the power of Scala... I'm really interested in your return of experience :D – mandubian Jun 27 '11 at 10:01

3 Answers3

7

It looks like you need an Option:

class ModelManager{
   def getModel(model: String) = model match {
      case "menu" => Some(classOf[Menu])
      case "articles" => Some(classOf[Articles])
      case _ => None
   }

   def deleteInstance(model:String, uid: Long) = 
      getModel(model) map { m => 
         Model.all(m).filter("uid", uid).get().delete()
      } getOrElse false
}

You can think of an Option as a container that can hold at most one element. The Option that holds an element x is Some(x). The empty Option is None. Option has several useful methods, including the map and getOrElse methods used above.

The map method applies a function to each element of the "container". Of course, if the container is None, it does nothing (except perhaps to change the static type of the Option). In your case (assuming delete returns a Boolean), the map method will change the Option[Class] into an Option[Boolean].

The getOrElse method returns the element of the option, if there is one, and otherwise returns a default value (false in this case).

Note that you can also simplify your implementation by using the condOpt method defined in PartialFunction:

class ModelManager{
   def getModel(model: String) = condOpt(model) {
      case "menu" => classOf[Menu]
      case "articles" => classOf[Articles]
   }

   def deleteInstance(model:String, uid: Long) = 
      getModel(model) map { m => 
         Model.all(m).filter("uid", uid).get().delete()
      } getOrElse false
}
Aaron Novstrup
  • 20,967
  • 7
  • 70
  • 108
2

It looks like getModel will return a Class sometimes, a Boolean others. In Scala, this would typically be modeled using the Either class:

def getModel(model: String) = {
    model match{
      case "menu" => Left(classOf[Menu])
      case "articles" => Left(classOf[Articles])
      case _ => Right(false)
    }

Left and Right represent the two possible choices of an Either. Callers of this method will need to inspect the return value (probably by using pattern matching as well) to decide if the method returned a Class or Boolean.

Adam Rabung
  • 5,232
  • 2
  • 27
  • 42
0

It seems you didn't close with parens in the right place. Did you mean this?

class ModelManager{
  def getModel(model: String) = {
    model match{
      // snip
    }
  } // end method here

  def deleteInstance(model:String, uid: Long) = {
    Model.all(getModel(model)).filter("uid", uid).get().delete()
  }    
} 

It does not look like you're trying to define a recursive method... Then you're likely to have other issues to resolve as you need a method that returns Class[_] not a combination of Boolean and Class[_] (which would be Any). So may be this would work better?

def getModel(model: String): Class[_] = {
  model match{
    case "menu" => classOf[Menu]
    case "articles" => classOf[Articles]
} // end method here
huynhjl
  • 41,520
  • 14
  • 105
  • 158