Hadley Wickham
2011-May-02 19:21 UTC
[Rd] Capturing the expression representing the body of a function
Hi all, What's the preferred way of capturing the expression representing the contents of a function? * body(write.csv) gives me a braced expression * body(write.csv)[-1] gives me a mangled call * as.list(body(write.csv)[-1]) gives me a list of calls * as.expression(as.list(body(write.csv)[-1])) is what I want but seems like too much work Any suggestions? Thanks, Hadley -- Assistant Professor / Dobelman Family Junior Chair Department of Statistics / Rice University http://had.co.nz/
Duncan Murdoch
2011-May-02 20:11 UTC
[Rd] Capturing the expression representing the body of a function
On 02/05/2011 3:21 PM, Hadley Wickham wrote:> Hi all, > > What's the preferred way of capturing the expression representing the > contents of a function? > > * body(write.csv) gives me a braced expression > * body(write.csv)[-1] gives me a mangled call > * as.list(body(write.csv)[-1]) gives me a list of calls > * as.expression(as.list(body(write.csv)[-1])) is what I want but seems > like too much work > > Any suggestions?The body of a function isn't an expression, it's a language object. A language object is represented internally as a pairlist, while an expression is represented as a generic vector, i.e. the thing that list() gives. Your 1st try gives you the language object. The other ones only work when the body consists of a call to `{`, as the body of most complex functions does, but not for simple ones like f <- function(x) 2*x So I would say your question should be: "What's the best way to construct an expression vector s.t. evaluating its elements in order is like evaluating the body of a function?" And the answer to that is something like body2expr <- function(f) { body <- body(f) if (typeof(body) == "language" && identical(body[[1]], quote(`{`))) as.expression(as.list(body[-1])) else as.expression(body) } Duncan Murdoch