get_obj_name {envnames} | R Documentation |
Return the name of an object at a given parent generation from an environment
Description
A practical use of this function is to retrieve the name of the object leading to a function's parameter in the function calling chain, at any parent generation.
Usage
get_obj_name(obj, n = 0, eval = FALSE, silent = TRUE)
Arguments
obj |
object whose name at a given parent generation is of interest. |
n |
number of parent generations to go back from the calling environment
to retrieve the name of the object that leads to |
eval |
whether to evaluate |
silent |
when |
Details
In particular, it provides a handy way of retrieving the name of a function's parameter
and use it in e.g. messages to the user describing the arguments received by the function.
In this context, it is a shortcut to calling as.list(environment())
, which returns
a list of parameter names and parameter values.
See the Examples section for an illustration.
This function goes back to each parent generation from the calling function's environment and at each of those parent generations it retrieves the name of the object that is part of the parameter chain leading to the calling function's parameter.
To illustrate: suppose we call a function f <- function(x)
by running the piece of code f(z)
,
and that f
calls another function g <- function(y)
by running the piece of code g(x)
.
That is, we have the parameter chain:
z -> x -> y
If, inside function g()
, we call get_obj_name()
as follows, we obtain respectively:
get_obj_name(y, n=1)
yields "x"
get_obj_name(y, n=2)
yields "z"
because these calls are telling "give me the name of object y
as it was called
n
levels up from the calling environment –i.e. from the environment of g()
.
Note that the results of these two calls are different from making the following two
deparse(substitute())
calls:
deparse(substitute(y, parent.frame(n=1)))
deparse(substitute(y, parent.frame(n=2)))
because these calls simply substitute
or evaluate y
at the n
-th parent generation.
If y
is not defined at those parent generations, the substitute()
calls return
simply "y"
.
On the contrary, the previous two calls to get_obj_name()
return the name of the object
in the parameter chain (z -> x -> y
) leading to y
, which is a quite different
piece of information.
When eval=TRUE, the result is the same as the result of deparse()
except for the following three cases:
if the object passed to
get_obj_name()
evaluates to a name, it returns that name, without any added quotes. For example, ifv = "x"
thenget_obj_name(v, eval=TRUE)
returns"x"
whiledeparse(v)
returns"\"x\""
.the result of
NULL
isNULL
instead of"NULL"
which is the case withdeparse()
.the result of a non-existent object is
NULL
, whiledeparse()
returns an error stating that the object does not exist.
When get_obj_name
operates on non-existent objects it works at follows:
when
eval=FALSE
it returns the name of the non-existent object enclosed in quotes (e.g.get_obj_name(nonexistent)
returns"nonexistent"
, assumingnonexistent
does not exist).when
eval=TRUE
it returns NULL.
Finally get_obj_name(NULL)
returns NULL
, while as.character(NULL)
returns as.character(0)
.
Value
The name of the object in the n
-th parent generation environment.
See Also
Examples
# Example 1:
# This example shows the difference between using get_obj_name() and deparse(substitute())
g <- function(y) { return(list(obj_name=get_obj_name(y, n=2, silent=FALSE),
substitute=deparse(substitute(y, parent.frame(n=2))) )) }
f <- function(x) { g(x) }
z = 3;
f(z) # After showing the names of objects as they
# are traversed in the parameter chain (silent=FALSE),
# this function returns a list where
# the first element (result of get_obj_name()) is "z"
# and the second element (result of deparse(substitute())) is "y".
# Note that 'z' is the object leading to object 'y'
# inside function g() if we follow the parameter names
# leading to 'y' in the function calling chain.
# Example 2:
# When eval=TRUE, get_obj_name() behaves the same way as deparse()
# (except for the cases noted in the Details section)
# because the values of all objects linked by the parameter chain
# are ALL the same.
g <- function(y) { return(list(obj_name=get_obj_name(y, n=2, eval=TRUE),
deparse=deparse(y))) }
f <- function(x) { g(x) }
z = 3
f(z) # Returns a list where both elements are equal to "3"
# because the output of get_obj_name() with eval=TRUE
# and deparse() are the same.
# Example 3:
# This example shows how we can use get_obj_name() to get the parameter names
# of non '...' parameters, which are then used in messages to the user.
# The advantage of using get_obj_name() as opposed to the hard-coded parameter name
# is that an error is raised if the parameter does not exist.
# An example is also shown that uses as.list(environment()), which clearly is more
# general... get_obj_name() should be used when referring to a couple of specific
# parameters.
f <- function(x, y, ...) {
cat("Arguments received by the function (using get_obj_name()) (explicit listing):\n")
cat(get_obj_name(x), ":", x, "\n")
cat(get_obj_name(y), ":", y, "\n")
cat("Arguments received by the function (using as.list(environment())) (automatic listing):\n")
paramsList = as.list(environment())
paramsNames = names(paramsList)
sapply(paramsNames, get_obj_name)
for (p in paramsNames) {
cat(p, ":", paramsList[[p]], "\n")
}
}
z = 5
extra_param = "a '...' parameter"
## Note: this exra parameter is NOT shown neither by get_obj_name()
## nor by as.list(environment())
f("test", z, extra_param)