简体   繁体   中英

How can I access the default value of a function argument?

Issue:

I want to use a function default_arg() to access the default value of arg in the context of a function func . However, I'd also like this function to be clever enough to guess which function and which argument I want in a couple of cases:

Case 1 - Used With Explicit Arguments:

tester_1 <- function(x = 1, y = 2, z = 3) {
  x * y + z
}
default_arg(x, tester_1) # this would evaluate to 1

Case 2 - Used Within a Function Body

tester_2 <- function(x = 1, y = 2, z = 3) {
  
  x_default <- default_arg(x) # this would evaluate to 1
  
  if(x < x_default) {
    stop(paste("x should be greater or equal to default value:", x_default))
  }

  x * y + z
}

Case 3 - Used as a Parameter:

tester_1(
  x = 2,
  y = 1,
  z = default_arg() # This would evaluate to 3
)

Current Approach:

I'm able to create something that works in cases 1 and 2, but I'm unsure how to approach Case 3. Here is the approach I'm using currently, using some functions from rlang :

default_arg <- function(arg, func = sys.function(sys.parent())) {
  formals(func)[[as_name(enquo(arg))]]
}

In my proposed solution, I also eliminated the rlang dependency (please see below):

default_arg <- function(arg = NULL, func = NULL) {
  if(deparse(substitute(arg)) == "NULL" & is.null(func))
  {
    arg = sys.calls()[[1]]
    val = as.character(arg); names(val) = names(arg)
    func = val[1]
    variable = names(which(val == "default_arg()"))
    return(formals(func)[[variable]])
  }
  if(is.null(func))
  {
    func = as.character(sys.call(sys.parent()))[1]
  }
  
  return(formals(func)[[deparse(substitute(arg))]])
}

default_arg(x, tester_1) # 1
default_arg(y, tester_1) # 2
default_arg(z, tester_1) # 3
tester_2() # 5
tester_1(x = 1, y = 2, z = default_arg()) # 5
tester_1(x = 1, y = default_arg(), z = 3) # 5
tester_1(x = default_arg(), y = 2, z = 3) # 5

Basically, it is just parsing the call and extracting the relevant information. Though this works, I am sure you can still make it neater by avoiding the conditionals. Good luck!

Best, Ventrilocus.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM