views:

360

answers:

10

I would like to write a code internal to my method that print which method/class has invoked it.

(My assumption is that I can't change anything but my method..)

How about other programming languages?

EDIT: Thanks guys, how about JavaScript? python? C++?

+3  A: 

the sequence of method calls is located in stack. this is how you get the stack: http://stackoverflow.com/questions/1069066/get-current-stack-trace-in-java then get previous item.

Andrey
Hehe, that links to an answer of mine! Thanks.
jjnguy
+4  A: 

If all you want to do is print out the stack trace and go hunting for the class, use

Thread.dumpStack();

See the API doc.

Jay R.
+1  A: 

Yes, it is possible.

Have a look at Thread.getStackTrace()

Tim
+16  A: 

This is specific to Java.

You can use Thread.currentThread().getStackTrace(). This will return an array of StackTraceElements.

The 2nd element in the array will be the calling method.

Example:

public void methodThatPrintsCaller() {
    StackTraceElement elem = Thread.currentThread.getStackTrace()[2];
    System.out.println(elem);

    // rest of you code
}
jjnguy
There are a couple of special cases to this that weren't suitable for a comment, I put them in their own answer.
Mark Peters
So Java arrays are 1-based now? ;)
Stroboskop
@strob, no. You will call `arr[2]` or the 2nd thing. (Technically it's the 3rd thing) (But, then what do you call the 0th thing?)
jjnguy
+1  A: 

This question deals with how to view the call stack in javascript.

rosscj2533
+2  A: 

Since you asked about other languages, Tcl gives you a command (info level) that lets you examine the call stack. For example, [info level -1] returns the caller of the current procedure, as well as the arguments used to call the current procedure.

Bryan Oakley
+1  A: 

In python you would use the traceback module. You can see examples there.

Daniel Velkov
+3  A: 

Justin has the general case down; I wanted to mention two special cases demonstrated by this snippit:

import java.util.Comparator;

public class WhoCalledMe {

    public static void main(String[] args) {
        ((Comparator)(new SomeReifiedGeneric())).compare(null, null);
        new WhoCalledMe().new SomeInnerClass().someInnerMethod();
    }

    public static StackTraceElement getCaller() {
        //since it's a library function we use 3 instead of 2 to ignore ourself
        return Thread.currentThread().getStackTrace()[3];
    }

    private void somePrivateMethod() {
        System.out.println("somePrivateMethod() called by: " + WhoCalledMe.getCaller());
    }

    private class SomeInnerClass {
        public void someInnerMethod() {
            somePrivateMethod();
        }
    }
}

class SomeReifiedGeneric implements Comparator<SomeReifiedGeneric> {
    public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) {
        System.out.println("SomeRefiedGeneric.compare() called by: " + WhoCalledMe.getCaller());
        return 0;
    }
}

This prints:

SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1)
somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14)

Even though the first is called "directly" from main() and the second from SomeInnerClass.someInnerMethod(). These are two cases where there is a transparent call made in between the two methods.

  • In the first case, this is because we are calling the bridge method to a generic method, added by the compiler to ensure SomeReifiedGeneric can be used as a raw type.
  • In the second case, it is because we are calling a private member of WhoCalledMe from an inner class. To accomplish this, the compiler adds a synthetic method as a go-between to override the visibility problems.
Mark Peters
Those are some good points.
jjnguy
+1  A: 

In Python, you should use the traceback or inspect modules. These will modules will shield you from the implementation details of the interpreter, which can differ even today (e.g. IronPython, Jython) and may change even more in the future. The way these modules do it under the standard Python interpreter today, however, is with sys._getframe(). In particular, sys._getframe(1).f_code.co_name provides the information you want.

kindall
+1  A: 

In Python you use the inspect module. Getting the function's name and file name is easy, as you see in the example below.

Getting the function itself is more work. I think you could use the __import__ function to import the caller's module. However you must somehow convert the filename to a valid module name.

import inspect

def find_caller():
    caller_frame = inspect.currentframe().f_back
    print "Called by function:", caller_frame.f_code.co_name
    print "In file           :", caller_frame.f_code.co_filename
    #Alternative, probably more portable way
    #print inspect.getframeinfo(caller_frame)

def foo():
    find_caller()

foo()
Eike