Get method name programmatically

1,556 views
Skip to first unread message

Eugen Labun

unread,
Mar 14, 2011, 9:14:17 AM3/14/11
to scala-user
Hi all,

I would like to get the name of the current method programmatically (from within this method).

In Java I would do it via throwing exception and search in the stack trace.
But this is expensive (in terms of time, not in LoC). There will be hundreds of such calls.

Is there eventually a more effective solution for Scala?


Regards,
Eugen Labun

Maxime Lévesque

unread,
Mar 14, 2011, 9:19:32 AM3/14/11
to Eugen Labun, scala-user

You don't need to throw and catch an excaption, you can use : 

 Thread.getStackTrace

I assume it's still pretty expensive though, and I don't know of a cheaper way.

Randall R Schulz

unread,
Mar 14, 2011, 9:21:01 AM3/14/11
to scala...@googlegroups.com
On Monday March 14 2011, Eugen Labun wrote:
> ...
> Eugen Labun


Perhaps we should start a new group / list, Scala-Dynamic,
for all the refugees from those other languages...


Randall Schulz

Eugen Labun

unread,
Mar 14, 2011, 9:34:36 AM3/14/11
to scala...@googlegroups.com
Thank you, Maxime,

this is still an improvement.

Eugen Labun

unread,
Mar 14, 2011, 9:36:46 AM3/14/11
to scala...@googlegroups.com
I'm not a refugee from dynamic languages. In principle I'm "strongly typed" :)

Kevin Wright

unread,
Mar 14, 2011, 9:38:00 AM3/14/11
to Eugen Labun, scala-user


On 14 Mar 2011 13:14, "Eugen Labun" <la...@gmx.net> wrote:
>
> Hi all,
>
> I would like to get the name of the current method programmatically (from within this method).
>

Can I ask why?

If it's not for exception reporting, then there may be a better way...

Eugen Labun

unread,
Mar 14, 2011, 9:50:45 AM3/14/11
to Kevin Wright, scala-user
I develop a parsing library. The idea is to automatically name each parser rule according to the
name of the defining method to (automatically) produce better debugging and error mesages.

Jim Powers

unread,
Mar 14, 2011, 9:54:59 AM3/14/11
to scala...@googlegroups.com
Wanting that kind of reflective information is not synonymous with
"dynamically typed language". Even in such languages reflection
coverage is spotty. For instance, getting the arity of a function in
Ruby (1.8.x) is not straight-forward.

--
Jim Powers

Paul Phillips

unread,
Mar 14, 2011, 9:59:04 AM3/14/11
to Eugen Labun, Kevin Wright, scala-user
On 3/14/11 6:50 AM, Eugen Labun wrote:
> I develop a parsing library. The idea is to automatically name each
> parser rule according to the name of the defining method to
> (automatically) produce better debugging and error mesages.

It's a legit reason and it comes up all the time for me: I end up with
lots of code which for one reason or another looks like

val foo = something("foo", ...)

Clearly in these contexts it would be useful to be able to refer to the
name of what you are. Just because one of the duplications is in quotes
doesn't mean it's not pure duplication.

If you ponder the problem a moment, it is odd that we have this first
class construct "this" to refer to "the current class" but nothing for
the current method. The method is (already, but far more so in java 7)
a discrete unit of functionality. Given a way to refer to the current
method one could do interesting things like...

thisMethod.recurse(5) // immunized against name changes
thisMethod.name
thisMethod.alternatives
... your idea here!

Jim Powers

unread,
Mar 14, 2011, 10:00:08 AM3/14/11
to scala...@googlegroups.com
On Mon, Mar 14, 2011 at 9:54 AMm, Jim Powers <j...@casapowers.com> wrote:
> Wanting that kind of reflective information is not synonymous with
> "dynamically typed language".  Even in such languages reflection
> coverage is spotty.  For instance, getting the arity of a function in
> Ruby (1.8.x) is not straight-forward.

Correction:
Grr. getting the "correct" arity (including "splats" and block
arguments) is not straight-forward.

Enough on Ruby, back to Scala.

--
Jim Powers

Jim Powers

unread,
Mar 14, 2011, 10:02:01 AM3/14/11
to scala-user
+1

This is on the roadmap right? ;-)

--
Jim Powers

Maxime Lévesque

unread,
Mar 14, 2011, 10:06:41 AM3/14/11
to Eugen Labun, Kevin Wright, scala-user

You could use proxying :

  http://cglib.sourceforge.net/

along with thread local storage, probably (but not garanteed)  more efficient than getCurrentStack ...

Kevin Wright

unread,
Mar 14, 2011, 10:10:26 AM3/14/11
to Paul Phillips, Eugen Labun, scala-user
Do you see any reason why this couldn't reasonably be prototyped via a plugin?

Ignoring recurse and alternatives for now, with the old chestnut that you'd want to synthesise methods after typing, it certainly looks like thisMethod.name would be easy enough to drop in directly after the parser phase.

--
Kevin Wright

gtalk / msn : kev.lee...@gmail.com
mail: kevin....@scalatechnology.com
vibe / skype: kev.lee.wright
quora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Eugen Labun

unread,
Mar 14, 2011, 10:18:32 AM3/14/11
to Paul Phillips, scala-user
Paul, thank you, you described my situation exactly!

And yeah, it would be very interesting to have "thisMethod".

Where can I read more about new features of methods in Java 7? (Haven't heard anything about what
you've mentioned.)

Eugen Labun

unread,
Mar 14, 2011, 10:20:37 AM3/14/11
to Maxime Lévesque, scala-user
Thank you, Maxime,

I will look into it.
(This will surely need some time.)

Eugen Labun

unread,
Mar 14, 2011, 10:34:24 AM3/14/11
to scala...@googlegroups.com
On 2011-03-14 15:18, Eugen Labun wrote:
> Where can I read more about new features of methods in Java 7? (Haven't heard anything about what
> you've mentioned.)

Found: that should be 'MethodHandle'

Mark Harrah

unread,
Mar 14, 2011, 10:39:26 AM3/14/11
to scala...@googlegroups.com
On Mon, 14 Mar 2011 06:59:04 -0700
Paul Phillips <pa...@improving.org> wrote:

> On 3/14/11 6:50 AM, Eugen Labun wrote:
> > I develop a parsing library. The idea is to automatically name each
> > parser rule according to the name of the defining method to
> > (automatically) produce better debugging and error mesages.
>
> It's a legit reason and it comes up all the time for me: I end up with
> lots of code which for one reason or another looks like
>
> val foo = something("foo", ...)
>
> Clearly in these contexts it would be useful to be able to refer to the
> name of what you are. Just because one of the duplications is in quotes
> doesn't mean it's not pure duplication.

This is a problem for me as well. A related problem for me is listing all such definitions in an object. I think addressing the two issues would make it possible to implement Enumeration without reflection, for example.

value x,y = Value
value z = Value(3)

translates to
val x = Value("x")
val y = Value("y")
val z = Value("z",3)
def values = Seq(x,y,z)

One could go further and write the above as:

value x,y,z(3)

-Mark

√iktor Klang

unread,
Mar 14, 2011, 11:02:24 AM3/14/11
to Paul Phillips, Eugen Labun, Kevin Wright, scala-user
+1!

--
Viktor Klang,
Code Connoisseur
Work:   Scalable Solutions
Code:   github.com/viktorklang
Follow: twitter.com/viktorklang
Read:   klangism.tumblr.com

Philippe Lhoste

unread,
Mar 14, 2011, 11:05:37 AM3/14/11
to scala...@googlegroups.com
On 14/03/2011 14:14, Eugen Labun wrote:
> I would like to get the name of the current method programmatically (from within this method).

Note that in Scala (or other functional languages), the information might not be totally
accurate, as you can have lot of references to a method, allowing to call it with
alternative names...

def someMethod(n: Int): Int = { ... }
val otherMethod: Int => Int = someMethod

println(someMethod(11))
println(otherMethod(42))

In the stack traces, we see twice someMethod.

Or perhaps I am mixing methods and functions, the frontier is still blurry in my mind...

--
Philippe Lhoste
-- (near) Paris -- France
-- http://Phi.Lho.free.fr
-- -- -- -- -- -- -- -- -- -- -- -- -- --

Paul Phillips

unread,
Mar 14, 2011, 11:15:25 AM3/14/11
to Philippe Lhoste, scala...@googlegroups.com
On 3/14/11 8:05 AM, Philippe Lhoste wrote:
> Note that in Scala (or other functional languages), the information
> might not be totally accurate, as you can have lot of references to a
> method, allowing to call it with alternative names...

No, those aren't methods.

> def someMethod(n: Int): Int = { ... }
> val otherMethod: Int => Int = someMethod

"otherFunction".

Eugen Labun

unread,
Mar 14, 2011, 11:41:28 AM3/14/11
to Paul Phillips, Philippe Lhoste, scala...@googlegroups.com
Yes, I should take care of many things if I stick with analysis of the stack trace solution.


E.g. how to split an entry from the stack trace into correct parts?

Actually I do it with the extractor

val MethodNameParts = """([\w$]*\.)+([^\(]+)(.*)""".r

used as: val MethodNameParts(path, name, rest) = methodName

Can I rely on the schema of this construction?
How should the parts be named more correctly?


E.g. is it a correct spliting or am I missing something:

entry: test$1line15$object$$iw$$iw$.(<console>:7)

parts: name: test$1
path: line15$object$$iw$$iw$.
rest: (<console>:7)

?

Paul Phillips

unread,
Mar 14, 2011, 11:49:40 AM3/14/11
to Eugen Labun, Philippe Lhoste, scala...@googlegroups.com
On 3/14/11 8:41 AM, Eugen Labun wrote:
> Yes, I should take care of many things if I stick with analysis of the stack trace solution.
>
> E.g. how to split an entry from the stack trace into correct parts?

I have a ton of code for this sort of thing, some of which is in trunk,
most of which isn't. Shoot, I had really meant to finish this for 2.9.
It basically works and is terribly useful, I just haven't put the
polish on the apple.

I put the branch in its current state on github. Look around the files
in this directory:


https://github.com/scala/scala/tree/funnel/src/compiler/scala/tools/funnel/

In terms of what's in trunk already, see Exceptional for a much reduced
preview of the above.


https://github.com/scala/scala/blob/master/src/compiler/scala/tools/nsc/util/Exceptional.scala

Eugen Labun

unread,
Mar 14, 2011, 11:58:34 AM3/14/11
to Paul Phillips, Philippe Lhoste, scala...@googlegroups.com
OK, I will look into. Thank you again, Paul!

Correction: the "entry" in the prev. post should be:
line15$object$$iw$$iw$.test$1(<console>:7)

Eugen Labun

unread,
Mar 14, 2011, 12:25:31 PM3/14/11
to scala...@googlegroups.com
Correction to the extractor:

val MethodNameParts = """((?:[\w$]*\.)+)([^\(]+)(.*)""".r

Eugen Labun

unread,
Mar 14, 2011, 1:01:42 PM3/14/11
to Paul Phillips, Philippe Lhoste, scala...@googlegroups.com
I must have been blind.
The stack trace consist of 'StackTraceElement's, which have 'getMethodName' and other useful
methods. No need to parse anything!

On 2011-03-14 16:49, Paul Phillips wrote:

richard emberson

unread,
Mar 14, 2011, 1:37:29 PM3/14/11
to scala...@googlegroups.com
Don't know if this is faster, but I've done this in the past:

import java.lang.management._
def getCallingFunctionName(depth: Int): String = {
val mxBean = ManagementFactory.getThreadMXBean
val threadInfo =mxBean.getThreadInfo(Thread.currentThread.getId,depth)
val elements = threadInfo.getStackTrace
elements(depth-1).getMethodName
}

--
Quis custodiet ipsos custodes

Eugen Labun

unread,
Mar 14, 2011, 2:03:07 PM3/14/11
to richard emberson, scala...@googlegroups.com
Thank you, Richard,

I will try it.

Nils Kilden-Pedersen

unread,
Mar 14, 2011, 2:21:58 PM3/14/11
to richard emberson, scala...@googlegroups.com
On Mon, Mar 14, 2011 at 12:37 PM, richard emberson <richard....@gmail.com> wrote:
Don't know if this is faster, but I've done this in the past:

import java.lang.management._
def getCallingFunctionName(depth: Int): String = {
 val mxBean = ManagementFactory.getThreadMXBean
 val threadInfo =mxBean.getThreadInfo(Thread.currentThread.getId,depth)
 val elements = threadInfo.getStackTrace
 elements(depth-1).getMethodName

}

Any reason to think that is faster than Thread.currentThread.getStackTrace?

richard emberson

unread,
Mar 14, 2011, 4:33:53 PM3/14/11
to Nils Kilden-Pedersen, scala...@googlegroups.com
This approach limits the size of the stack trace requested.
But, like I said, I don't know if its faster.

I also then cache the method name based upon the method
body (() => R) and look up the name from the cache on
subsequent calls.

--
Quis custodiet ipsos custodes

Nils Kilden-Pedersen

unread,
Mar 14, 2011, 5:17:34 PM3/14/11
to richard emberson, scala...@googlegroups.com
On Mon, Mar 14, 2011 at 3:33 PM, richard emberson <richard....@gmail.com> wrote:
This approach limits the size of the stack trace requested.

I see. I hadn't noticed that. Thanks.

Adriaan Moors

unread,
Mar 15, 2011, 12:23:56 PM3/15/11
to scala-user
On Mon, Mar 14, 2011 at 2:14 PM, Eugen Labun <la...@gmx.net> wrote:
I would like to get the name of the current method programmatically (from within this method).

Is there eventually a more effective solution for Scala?
I think there might be a special kind of manifest that provides this kind of information in the near future (post 2.9.0 in any case).

cheers
adriaan

Andrés Testi

unread,
Mar 17, 2011, 9:15:45 AM3/17/11
to scala-user
I agree! Could be something like:

def assertTrue(cond: Boolean)(implicit m: MethodManifest) = ....

- Andrés

Eugen Labun

unread,
Mar 17, 2011, 10:01:18 AM3/17/11
to scala...@googlegroups.com
Thank you, Adriaan,

this is a very good news! Looking forward to it.

--
Eugen

On 2011-03-15 17:23, Adriaan Moors wrote:

Naftoli Gugenheim

unread,
Apr 3, 2011, 9:08:58 PM4/3/11
to Eugen Labun, scala...@googlegroups.com
If there's some way to use objects instead of a current method then you could use its class name. Lift uses this technique to know the name of Mapper fields, and to back RequestVar etc.'s contents.

Eugen Labun

unread,
Apr 4, 2011, 7:05:21 AM4/4/11
to Naftoli Gugenheim, scala...@googlegroups.com
Naftoli, could you eventually point to the corresponding Lift code?
(Sorry, I'm not yet familiar with Lift)

Naftoli Gugenheim

unread,
Apr 5, 2011, 10:48:29 PM4/5/11
to Eugen Labun, scala...@googlegroups.com
Are you looking for the code that runs the reflection or demonstration code?

Eugen Labun

unread,
Apr 6, 2011, 11:35:52 AM4/6/11
to scala...@googlegroups.com
Thank you, Naftoli. I will look into.
Reply all
Reply to author
Forward
0 new messages