any way to get a method handle in scala?

235 views
Skip to first unread message

Ittay Dror

unread,
Aug 29, 2012, 7:52:44 AM8/29/12
to scala-user
Hi,

Given:

class Foo {
  def bar(s: String) = ???
}

Is there a way to get a reference to 'bar' in a type safe way, so that I can inspect its argument list and invoke it at runtime?

This is in contrast to `_.bar _` that wraps it in a function object that cannot be inspected (or maybe there is a way with the new reflection?) or using the method name as string with is not type safe.

Regards,
Ittay

Dennis Haupt

unread,
Aug 29, 2012, 8:17:07 AM8/29/12
to Ittay Dror, scala...@googlegroups.com
what do you mean by type safe?

> -------- Original-Nachricht --------
> Datum: Wed, 29 Aug 2012 14:52:44 +0300
> Von: Ittay Dror <ittay...@gmail.com>
> An: scala-user <scala...@googlegroups.com>
> Betreff: [scala-user] any way to get a method handle in scala?

Ittay Dror

unread,
Aug 29, 2012, 9:23:30 AM8/29/12
to Dennis Haupt, scala...@googlegroups.com
not getting it by using a string name .

Dennis Haupt

unread,
Aug 29, 2012, 10:28:43 AM8/29/12
to Ittay Dror, scala...@googlegroups.com
is what you want to do a function wrapper with generic type information available at runtime?
should be possible, create your own function wrappers with manifests.

> -------- Original-Nachricht --------
> Datum: Wed, 29 Aug 2012 16:23:30 +0300
> Von: Ittay Dror <ittay...@gmail.com>
> An: Dennis Haupt <h-s...@gmx.de>
> CC: scala...@googlegroups.com
> Betreff: Re: [scala-user] any way to get a method handle in scala?

Ittay Dror

unread,
Aug 29, 2012, 10:48:33 AM8/29/12
to Dennis Haupt, scala...@googlegroups.com
There are manifests for methods?

Dennis Haupt

unread,
Aug 29, 2012, 10:59:20 AM8/29/12
to Ittay Dror, scala...@googlegroups.com
i was thinking:

class ManifestFunction1[R:Manifest,T:Manifest](wrapped:Function1[R,T]) {
....
}

val magic = new manifestfunction(method _)

untested, but should work

> -------- Original-Nachricht --------
> Datum: Wed, 29 Aug 2012 17:48:33 +0300

Daniel Sobral

unread,
Aug 29, 2012, 12:58:19 PM8/29/12
to Ittay Dror, scala-user
Not really. You can approach that somewhat using reflection and
macros, to get a MethodSymbol. You still need to pass a String, but
the macro will make it checked at compile time.

Now, to invoke it you need a method mirror, and a method mirror
requires an instance mirror. All this mirroring is necessary because
to find stuff you need to go through a class loader.
--
Daniel C. Sobral

I travel to the future all the time.

Flávio W. Brasil

unread,
Aug 30, 2012, 10:08:28 AM8/30/12
to Daniel Sobral, Ittay Dror, scala-user
It's possible to do reflection in a type-safe way using the scala.reflect.Code.
I've been using this trick for a while in a non open source project. I extracted the code to a LGPL project at Github.
It is very based on heuristics and I've not finished to port the unit tests. Probably the framework will be re-written or deprecated with 2.10 reflection.


import net.fwbrasil.sReflection.SReflection._


object Example extends App {

class MyClass {

var string = "a"

def method(s: String) = {

string = s

}

}


val sField = classOf[MyClass].sField(_.string).get

val sMethod = classOf[MyClass].sMethod[String](_.method(_)).get


val obj = new MyClass

require(sField.get(obj) == "a")

sMethod.invoke(obj, "b")

require(sField.get(obj) == "b")

}


-- 
Flávio W. Brasil

Daniel Sobral

unread,
Aug 30, 2012, 6:59:00 PM8/30/12
to Flávio W. Brasil, Ittay Dror, scala-user
Mmmmm. I had not thought of having it ask for a function and get the
eta expansion of the method. Workable indeed.
Reply all
Reply to author
Forward
0 new messages