name of current function

552 views
Skip to first unread message

Mark Volkmann

unread,
May 3, 2009, 9:58:43 AM5/3/09
to clo...@googlegroups.com
Is there a special variable that holds the name of the currently
running function so it can be output in a logging message?

I'm thinking of something like this:

(defn my-function []
(println "entered" *current-function*)
...
)

--
R. Mark Volkmann
Object Computing, Inc.

e

unread,
May 3, 2009, 10:37:57 AM5/3/09
to clo...@googlegroups.com
you might already have this way ... but probably only during debug since it throws an exception and parses it.

http://forums.sun.com/thread.jspa?threadID=548409&start=0

that page also mentions something that sounds better: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StackTraceElement.html

Stephen C. Gilardi

unread,
May 3, 2009, 11:29:40 AM5/3/09
to clo...@googlegroups.com

On May 3, 2009, at 9:58 AM, Mark Volkmann wrote:

> Is there a special variable that holds the name of the currently
> running function so it can be output in a logging message?
>
> I'm thinking of something like this:
>
> (defn my-function []
> (println "entered" *current-function*)
> ...
> )

Maintaining such a var by updating its value on every function entry
would be prohibitively expensive in runtime in the general case.

As e mentioned, it's possible to use the exception system to get the
name of the current function in a particular case.

Here's an example:

[debug_utils.clj]

(ns debug-utils
(:use [clojure.contrib.str-utils :only (re-sub)]))

(defn unmangle
"Given the name of a class that implements a Clojure function,
returns
the function's name in Clojure"
[class-name]
(re-sub #"^(.+)\$(.+)__\d+$" "$1/$2" class-name))

(defmacro current-function-name []
"Returns a string, the name of the current Clojure function"
`(-> (Throwable.) .getStackTrace first .getClassName unmangle))

[repl]

Clojure 1.0.0-RC1-SNAPSHOT
user=> (use 'debug-utils)
nil
user=> (defn my-cool-func []
(println "entered" (current-function-name))
5)
#'user/my-cool-func
user=> (my-cool-func)
entered user/my_cool_func
5
user=>

--Steve

Stephen C. Gilardi

unread,
May 3, 2009, 11:46:36 AM5/3/09
to clo...@googlegroups.com

On May 3, 2009, at 11:29 AM, Stephen C. Gilardi wrote:

> #'user/my-cool-func
> user=> (my-cool-func)
> entered user/my_cool_func
> 5

But my_cool_func isn't my-cool-func...

Corrected code in "unmangle" in case anybody wants to use it sometime:

(ns debug-utils
(:use [clojure.contrib.str-utils :only (re-sub)]))

(defn unmangle
"Given the name of a class that implements a Clojure function,
returns

the function's name in Clojure. Note: If the true Clojure function
name
contains any underscores (a rare occurrence), the unmangled name will
contain hyphens at those locations instead."
[class-name]
(.replace


(re-sub #"^(.+)\$(.+)__\d+$" "$1/$2" class-name)

\_ \-))

(defmacro current-function-name []
"Returns a string, the name of the current Clojure function"
`(-> (Throwable.) .getStackTrace first .getClassName unmangle))

[repl]

Clojure 1.0.0-RC1-SNAPSHOT
user=> (use 'debug-utils)
nil
user=> (defn my-cool-func []
(println "entered" (current-function-name))
5)
#'user/my-cool-func
user=> (my-cool-func)

entered user/my-cool-func
5
user=>

--Steve

André Thieme

unread,
May 3, 2009, 2:03:54 PM5/3/09
to Clojure
On 3 Mai, 15:58, Mark Volkmann <r.mark.volkm...@gmail.com> wrote:
> Is there a special variable that holds the name of the currently
> running function so it can be output in a logging message?
>
> I'm thinking of something like this:
>
> (defn my-function []
>   (println "entered" *current-function*)
>   ...
> )

One way to solve this could be to write an anaphoric macro
over defn. Example:
(defmacro defnamed [name params & body]
`(let [~'*fn-name* ~(str name)]
(defn ~name ~params
~@body)))

Then you can
(defnamed foo [a b]
(println (+ a b) *fn-name*))

When the compiler is clever enough it sees that *fn-name*
is a constant and thus can replace each occurence in the
body with the string.

Reply all
Reply to author
Forward
0 new messages