Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine function name within that function

Tags:

r

How can I get the function's name within that non-anonymous function? below I assume there's a function or process to do this called magical_r_function() and what the expected outputs would be.

my_fun <- function(){
      magical_r_function()
}
my_fun()
## [1] "my_fun"


foo_bar <- function(){
      magical_r_function()
}
foo_bar()
## [1] "foo_bar"

ballyhoo <- function(){
    foo_bar()
}
ballyhoo()
## [1] "foo_bar"

tom_foolery <- foo_bar
tom_foolery()
## [1] "tom_foolery"
like image 365
Tyler Rinker Avatar asked Apr 27 '20 22:04

Tyler Rinker


People also ask

How do you define a function name?

JavaScript Function Syntax Function names can contain letters, digits, underscores, and dollar signs (same rules as variables). The parentheses may include parameter names separated by commas: (parameter1, parameter2, ...) Function parameters are listed inside the parentheses () in the function definition.

What is __ func __ in Python?

It's this method object that has the __func__ attribute, which is just a reference to the wrapped function. By accessing the underlying function instead of calling the method, you remove the typecheck, and you can pass in anything you want as the first argument.

How do you print a function name in Python?

Use the __name__ Property to Get the Function Name in Python __name__ . It will then return the function name as a string. The below example declares two functions, calls them, and prints out their function names. Note that this solution also works with the imported and pre-defined functions.


3 Answers

as.character(match.call()[[1]])

Demo:

my_fun <- function(){
  as.character(match.call()[[1]])
}
my_fun()
# [1] "my_fun"
foo_bar <- function(){
  as.character(match.call()[[1]])
}
foo_bar()
# [1] "foo_bar"
ballyhoo <- function(){
  foo_bar()
}
ballyhoo()
# [1] "foo_bar"
tom_foolery <- foo_bar
tom_foolery()
# [1] "tom_foolery"
like image 173
r2evans Avatar answered Oct 20 '22 13:10

r2evans


Try sys.call(0) if a call object output is ok or deparse that if you just want the name as a character string. Below are a couple of tests of this. sys.call returns both the name and the arguments and the [[1]] picks out just the name.

my_fun <- function() deparse(sys.call(0)[[1]])

g <- function() my_fun()

my_fun()
## [1] "my_fun"

g()
## [1] "my_fun"

Function names

Note that functions don't actually have names. What we regard as function names are actually just variables that hold the function and are not part of the function itself. A function consists of arguments, body and an environment -- there is no function name among those constituents.

Anonymous functions

Furthermore one can have anonymous functions and these might return strange results when used with the above.

sapply(1:3, function(x) deparse(sys.call(0)[[1]]))
## [1] "FUN" "FUN" "FUN"

Edge cases

There do exist some situations, particularly involving anonymous functions, where deparse will return more than one element so if you want to cover such edge cases use the nlines = 1 argument to deparse or use deparse(...)[[1]] or as mentioned by @Konrad Rudolph by using deparse1 in R 4.0.0.

Map(function(x) deparse(sys.call(0)[[1]], nlines = 1), 1:2)
## [[1]]
## [1] "function (x) "
## 
## [[2]]
## [1] "function (x) "

Map(function(x) deparse(sys.call(0)[[1]]), 1:2)  # without nlines=1
## [[1]]
## [1] "function (x) "             "deparse(sys.call(0)[[1]])"
##
## [[2]]
## [1] "function (x) "             "deparse(sys.call(0)[[1]])"

Other

Recall. If the reason you want the function name is to recursively call the function then use Recall() instead. From the help file:

fib <- function(n)
   if(n<=2) { if(n>=0) 1 else 0 } else Recall(n-1) + Recall(n-2)
fib(4)
## [1] 3

warning and stop These both issue the name of the function along with whatever argument is passed to them so there is no need to get the current function name.

testWarning <- function() warning("X")
testWarning()
## Warning message:
## In testWarning() : X
like image 23
G. Grothendieck Avatar answered Oct 20 '22 13:10

G. Grothendieck


We can also use

my_fun <- function(){
  as.character(as.list(sys.calls()[[1]])[[1]])
 }

my_fun()
#[1] "my_fun"
like image 5
akrun Avatar answered Oct 20 '22 12:10

akrun