sys.parent {base} | R Documentation |
Functions to Access the Function Call Stack
Description
These functions provide access to environment
s
(‘frames’ in S terminology) associated with functions further
up the calling stack.
Usage
sys.call(which = 0)
sys.frame(which = 0)
sys.nframe()
sys.function(which = 0)
sys.parent(n = 1)
sys.calls()
sys.frames()
sys.parents()
sys.on.exit()
sys.status()
parent.frame(n = 1)
Arguments
which |
the frame number if non-negative, the number of frames to go back if negative. |
n |
the number of generations to go back. (See the ‘Details’ section.) |
Details
.GlobalEnv
is given number 0 in the list of frames.
Each subsequent function evaluation increases the frame stack by 1.
The call, function definition and the environment for evaluation
of that function are returned by sys.call
, sys.function
and sys.frame
with the appropriate index.
sys.call
, sys.function
and sys.frame
accept
integer values for the argument which
. Non-negative values of
which
are frame numbers starting from .GlobalEnv
whereas negative values are counted back from the frame number of the
current evaluation.
The parent frame of a function evaluation is the environment in which
the function was called. It is not necessarily numbered one less than
the frame number of the current evaluation, nor is it the environment
within which the function was defined. sys.parent
returns the
number of the parent frame if n
is 1 (the default), the
grandparent if n
is 2, and so on. See also the ‘Note’.
sys.nframe
returns an integer, the number of the current frame
as described in the first paragraph.
sys.calls
and sys.frames
give a pairlist of all the
active calls and frames, respectively, and sys.parents
returns
an integer vector of indices of the parent frames of each of those
frames.
Notice that even though the sys.
xxx functions (except
sys.status
) are interpreted, their contexts are not counted nor
are they reported. There is no access to them.
sys.status()
returns a list with components sys.calls
,
sys.parents
and sys.frames
, the results of calls to
those three functions (which will include the call to
sys.status
: see the first example).
sys.on.exit()
returns the expression stored for use by
on.exit
in the function currently being evaluated.
(Note that this differs from S, which returns a list of expressions
for the current frame and its parents.)
parent.frame(n)
is a convenient shorthand for
sys.frame(sys.parent(n))
(implemented slightly more efficiently).
Value
sys.call
returns a call, sys.function
a function
definition, and sys.frame
and parent.frame
return an
environment.
For the other functions, see the ‘Details’ section.
Note
Strictly, sys.parent
and parent.frame
refer to the
context of the parent interpreted function. So internal
functions (which may or may not set contexts and so may or may not
appear on the call stack) may not be counted, and S3 methods can also do
surprising things.
As an effect of lazy evaluation, these functions look at the call stack at the time they are evaluated, not at the time they are called. Passing calls to them as function arguments is unlikely to be a good idea, but these functions still look at the call stack and count frames from the frame of the function evaluation from which they were called.
Hence, when these functions are called to provide default values for
function arguments, they are evaluated in the evaluation of the called
function and they count frames accordingly (see e.g. the envir
argument of eval
).
References
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988)
The New S Language.
Wadsworth & Brooks/Cole. (Not parent.frame
.)
See Also
eval
for a usage of sys.frame
and parent.frame
.
Examples
require(utils)
## Note: the first two examples will give different results
## if run by example().
ff <- function(x) gg(x)
gg <- function(y) sys.status()
str(ff(1))
gg <- function(y) {
ggg <- function() {
cat("current frame is", sys.nframe(), "\n")
cat("parents are", sys.parents(), "\n")
print(sys.function(0)) # ggg
print(sys.function(2)) # gg
}
if(y > 0) gg(y-1) else ggg()
}
gg(3)
t1 <- function() {
aa <- "here"
t2 <- function() {
## in frame 2 here
cat("current frame is", sys.nframe(), "\n")
str(sys.calls()) ## list with two components t1() and t2()
cat("parents are frame numbers", sys.parents(), "\n") ## 0 1
print(ls(envir = sys.frame(-1))) ## [1] "aa" "t2"
invisible()
}
t2()
}
t1()
test.sys.on.exit <- function() {
on.exit(print(1))
ex <- sys.on.exit()
str(ex)
cat("exiting...\n")
}
test.sys.on.exit()
## gives 'language print(1)', prints 1 on exit
## An example where the parent is not the next frame up the stack
## since method dispatch uses a frame.
as.double.foo <- function(x)
{
str(sys.calls())
print(sys.frames())
print(sys.parents())
print(sys.frame(-1)); print(parent.frame())
x
}
t2 <- function(x) as.double(x)
a <- structure(pi, class = "foo")
t2(a)