[Roxygen-devel] Parsing roxgen blocks
Vitalie Spinu
spinuvit at gmail.com
Wed Aug 29 15:43:25 CEST 2012
>> Hadley Wickham <hadley at rice.edu>
>> on Wed, 29 Aug 2012 08:16:07 -0500 wrote:
> [splitting out into separate emails instead of one huge one]
>> Not that difficult, S4 always leave traces in the evaluation
>> environment, objects starting with:
>>
>> methods:::.TableMetaPattern()
>> [1] "^[.]__T__"
>> methods:::.ClassMetaPattern()
>> [1] "^[.]__C__"
>>
>> Inspecting those, you know exactly what was installed.
> Yeah, that's the easy part ;) Now how do you find which comment block
> they were associated with?
> As far as I can see, there's no other way to do this apart from
> parsing the call. I also don't see another way to document user
> created functions that modify the global state - e.g. add_roccer in
> roxygen3 (this wouldn't be necessary if we used S4, but the principle
> remains).
HW> Could you flesh out this example a bit more? I don't understand why
HW> you'd want to document objects that aren't evaluated by the user.
>>
>> Ah sorry, that was stupid. I meant
>>
>> eval({ a <- generate_object_a()
>> b <- generate_object_b()})
>>
>> Roxygen can make a convention if two declarations are followed
>> imidiately after each over they souled be documented in the same
>> roxy-doc and same Rd file:
>>
>> foo <- function(a) ..
>> boo <- function(a) ..
>>
>> will put both foo and boo in the same file. Curently one needs two
>> documentation blocks and rdname tag if I am not mistaken.
> Again, the challenge is to connect the objects to the roxygen block.
> Without parsing the call, how do you know that the comment block
> should be attached to a and b?
> One option would be to evaluate each source block as you encounter it.
> That would resolve the problem above (and would make it possible to do
> `my_class <- setClass` and still know that it was creating a class).
> The problem is that the S4 functions don't seem to be very good at
> returning what they're created:
Precisely what I had in mind (I was convinced that roxygen is already
doing that and didn't bother to explain).
Each code chunk should be evaluated in a new environment. Then
environment is inspected and all the new objects/classes/methods are
returned.
There might be an environment (or list) in roxygen namespace holding all
the object guessers (roxy_env_inspectors?). Each of them is called and
should return a list of new objects detected.
The basic one just looks for normally assigned objects,
roxy_env_inspector.S3 looks for S3 tables *in* the evaluation
environment, roxy_env_inspector.S4_classes looks in class table and gets
the classes defined, roxy_env_inspector.S4_methods searches the S4
table.
If a package declares some wiredo side effect initialization (which is
pretty rare) it should define roxy_env_inspector.Wierdo_thing and add it
to roxy_env_inspectors environment (which should not be sealed in the
package).
>> a <- setMethod("plot", "numeric", function(x, ...) {})
>> str(a)
> chr "plot"
> Which means you'd have to compare states of all the S4 class/method
> tables before and after each call. That seems slow and error prone to
> me.
Each call to meta functions setClass, setMethod etc creates a table *in*
the evaluation env, if it is a top environment (environment should be
explicitly designated as a top environment for this to work).
Indeed, as far as I can remember, S4 methods an generics are also copied
to the central table for efficiency, but roxygen need not care about
those, local tables are enough.
> If you wanted to write some code to do it, I'd definitely be happy to
> consider it, but given that my current system works, I'm not in a big
> hurry to rewrite it.
Ok, I will wrap up a proof-of-the-concept code.
Vitalie
More information about the Roxygen-devel
mailing list