Rev 18976 | Blame | Last modification | View Log | Download | RSS feed
\name{trace}\alias{trace}\alias{untrace}%% private\alias{.untracedFunction}\alias{.makeTracedFunction}\title{ Interactive Tracing and Debugging of Calls to a Function orMethod}\description{A call to \code{trace} modified version of a function or of a formalmethod can be created to do arbitrary computations (usually to callan interactive browser) at various places in the call. A call to\code{untrace} cancels the tracing.}\usage{trace(what, tracer, exit, at, print = TRUE, signature = NULL)untrace(what)}\arguments{\item{what}{ The name (quoted or not) of a function to be traced oruntraced. More than one name can be given in the quoted form, withthe same action applied to each one. }\item{tracer}{Either a function or an unevaluated expression. Thefunction will be called or the expression will be evaluated eitherat the beginning of the call, or before steps in the call ifargument \code{at} is supplied.See the details section.}\item{exit}{ Either a function or an unevaluated expression. Thefunction will be called or the expression will be evaluated onexiting the function.See the details section. }\item{at}{ An optional numeric vector. If supplied, \code{tracer}will be called just before the corresponding step in the body of thefunction.See the details section. }\item{print}{ If \code{TRUE}, a descriptive line is printed before anytrace expression is evaluated.}\item{signature}{ If this argument is supplied, it should be asignature for a method for function \code{what}. In this case, themethod, and \emph{not} the function itself, is traced. }}\details{The \code{trace} function operates by constructing a revised versionof the function (or of the method, if \code{signature} is supplied),and assigning the new object back where the original was found.However, for back compatibility, if \code{trace} is called with onlythe \code{what} argument, it calls the primitive trace function in thebase package.The object constructed by \code{trace} is from a class that extends\code{"function"} and which contains the original, untraced version.A call to \code{untrace} re-assigns the untraced version extractedfrom the current, traced version.If the argument \code{tracer} or \code{exit} is the name of afunction, the tracing expression will be a call to that function, withno arguments. This is the easiest and most common case, with thefunctions \code{\link{browser}} and \code{\link{recover}} thelikeliest candidates; the former browses in the frame of the functionbeing traced, and the latter allows browsing in any of the currentlyactive calls.The \code{tracer} or \code{exit} argument can also be an unevaluatedexpression (such as returned by a call to \code{\link{quote}} or\code{\link{substitute}}). This expression itself is inserted in thetraced function, so it will typically involve arguments or localobjects in the traced function. An expression of this form is usefulif you only want to interact when certain conditions apply (and inthis case you probably want to supply \code{print=FALSE} in the callto \code{trace} also).When the \code{at} argument is supplied, it should be a vector ofintegers referring to the substeps of the body of the function (thisonly works if the body of the function is enclosed in \code{{ ...}}. Inthis case \code{tracer} is \emph{not} called on entry, but insteadjust before evauating each of the steps listed in \code{at}. (Hint:you don't want to try to count the steps in the printed version of afunction; instead, look at \code{as.list(body(f))} to get the numbersassociated with the steps in function \code{f}.)An intrinsic limitation in the \code{exit} argument is that it won'twork if the function itself uses \code{on.exit}, since the existingcalls will override the one supplied by \code{trace}.Tracing does not nest. Any call to \code{trace} replaces previouslytraced versions of that function or method, and \code{untrace} alwaysrestores an untraced version. (Allowing nested tracing has too manypotentials for confusion and for accidentally leaving traced versionsbehind.)Tracing primitive functions (builtins and specials) from the basepackage works, but only by a special mechanism and not veryinformatively. Tracing a primitive causes the primitive to bereplaced by a function with argument \dots (only). You can get a bitof information out, but not much. A warning message is issued when\code{trace} is used on a primitive.The practice of saving the traced version of the function back wherethe function came from means that tracing carries over from onesession to another, \emph{if} the traced function is saved in thesession image. (In the next session, \code{untrace} will remove thetracing.) On the other hand, functions that were in a package, not inthe global environment, are not saved in the image, so tracing expireswith the session for such functions.Tracing a method is basically just like tracing a function, with theexception that the traced version is stored by a call to\code{\link{setMethod}} rather than by direct assignment, and so isthe untraced version after a call to \code{untrace}.The version of \code{trace} described here is largely compatible withthe version in S-Plus, although the two work by entirely differentmechanisms. The S-Plus \code{trace} uses the session frame, with theresult that tracing never carries over from one session to another (Rdoes not have a session frame). Another relevant distinction hasnothing directly to do with \code{trace}: The browser in S-Plusallows changes to be made to the frame being browsed, and the changeswill persist after exiting the browser. The R browser allows changes,but they disappear when the browser exits. This may be relevant inthat the S-Plus version allows you to experiment with code changesinteractively, but the R version does not. (A future revision mayinclude a ``destructive'' browser for R.)}\value{The traced function(s) name(s). The relevant consequence is theassignment that takes place.}\seealso{\code{\link{browser}} and \code{\link{recover}}, the likeliesttracing functions;also, \code{\link{quote}} and \code{\link{substitute}} forconstructing general expressions.}\examples{f <- function(x, y) {y <- pmax(y, .001)x ^ y}## arrange to call the browser on entering and exiting## function ftrace("f", browser, exit = browser)## instead, conditionally assign some data, and then browse## on exit, but only then. Don't bother me otherwisetrace("f", quote(if(any(y < 0)) yOrig <- y),exit = quote(if(exists("yOrig")) browser()),print = FALSE)## trace a utility function, with recover so we## can browse in the calling functions as well.trace("as.matrix", recover)## turn off the tracinguntrace(c("f", "as.matrix"))}\keyword{ programming }\keyword{ debugging }