4

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?

Freewind
  • 193,756
  • 157
  • 432
  • 708

3 Answers3

9

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
Kevin Wright
  • 49,540
  • 9
  • 105
  • 155
  • @Freewind - Okay, I've updated my answer (and the project) with a solution to the problem of building mirrors from a class name string. – Kevin Wright Mar 04 '11 at 14:28
2

This question has some insight on how it is done in Java: Is there a way to obtain names of method parameters in Java?

Community
  • 1
  • 1
thoredge
  • 12,237
  • 1
  • 40
  • 55
  • thank you very much, that's very helpful. I still have a question, why not scala add this feature? I don't think it's a problem. – Freewind Mar 04 '11 at 10:12
  • 1
    If there is no such feature in scala, then that is probably because java doesn't have one directly yet; and that could mean future trouble. Here is a discussion about parameter names in Java 6 for more insight (I don't know where the feature stands in Java 7): http://paulhammant.com/blog/parameter-names-for-java6-answer.html I believe scala do use the parameter names in compile time for named parameters. That'll have to come from the debug information of the class. – thoredge Mar 04 '11 at 10:25
  • Actually, it comes from the "scala signature", which is encoded as a sequence of bytes in an annotation named `ScalaSig` attached to every class file that scalac emits. – Kevin Wright Mar 04 '11 at 14:30
  • Ah, I stand corrected. Sounds like a much more trustworthy solution as well. – thoredge Mar 04 '11 at 16:27
1

Why not just using different method names (to reflect the parameters that may be passed)? Like, craeteWithNameAndAgeAndGender (pretty standard approach). You won't anyways be able to have multiple methods with the same names(/arity/parameter types and order) and just different parameter names - method overloading doesn't work this way.

Vasil Remeniuk
  • 20,519
  • 6
  • 71
  • 81
  • maybe I haven't express clearly. I used `reflection` to get the method names, and if I want to auto-binding, I have to get the method names. But I can't get them by java relection. – Freewind Mar 04 '11 at 09:42