Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get the parameter names of a method in scala

As far as I know, we can't do this in Java. Can we do this in scala?

Suppose there is a method as following:

def insert(name:String, age:Int) {
    // insert new user
}

Is it possible to get the parameter names name and age in scala?


UPDATE

I want to do this, because I want to bind the parameters of methods automaticlly.

For example, this is a web app, it has some actions defined as:

class UsersController extends Controller {
    def create(name: String, age: Int) {
          // insert the user
    }
}

A client clicked the submit button of a creating-user form. The url will be /users/create and with some parameters sending.

On the server side, when we get a url named /users/create, we will find a method create in the controller UsersController, found one now. Then I have to get the parameter names of that method, then we can get the values of them:

val params = getParamsFromRequest()
val method = findMethodFromUrl("/users/create")
val paramNames = getParamNamesOfMethod(method)
val paramValues = getValues(params, paramNames)

// then invoke
method.invoke(controller, paramValues)

Now, the key is how to get the parameter names of a method?

like image 521
Freewind Avatar asked Dec 16 '22 16:12

Freewind


1 Answers

It's still very much a work in progress, but you should be able to:

import scalaj.reflect._
for {
  clazz <- Mirror.ofClass[UsersController].toSeq
  method <- clazz.allDefs.find(_.name == "insert").toSeq
  params <- method.flatParams
} yield params

Sorry about the toSeqs, they're to work around a known issue using Options in a for-comprehension.

Please don't push it too hard, it's still very young and fragile. I'm certainly not at the stage yet where I'd accept bug reports :)

UPDATE

Well... I know that I said I'm not accepting bug reports, but this one seemed so useful that I've pushed it up to github anyway.

To do the job dynamically (from a String class name):

import scalaj.reflect._
for {
  clazz <- Option(Class forName "x.y.UsersController")
  mirror <- Mirror.ofClass(clazz).toSeq
  method <- mirror.allDefs.find(_.name == "insert").toSeq
  params <- method.flatParams
} yield params
like image 142
Kevin Wright Avatar answered Dec 28 '22 23:12

Kevin Wright