[Roxygen-devel] roxygen3

Vitalie Spinu spinuvit at gmail.com
Tue Aug 28 21:59:24 CEST 2012


  >> Hadley Wickham <hadley at rice.edu>
  >> on Tue, 28 Aug 2012 11:49:16 -0500 wrote:

  HW> I've also been wondering about splitting "roxygen3" into two packages
  HW> - one that defines all the basic objects etc and one that creates all
  HW> the tags.  

An add-on package would have to load both right? So what is the
advantage of the split then?

  HW> On Tue, Aug 28, 2012 at 11:46 AM, Hadley Wickham <hadley at rice.edu> wrote:
  >> 
  >>> May be I am missing the point here, but it looks to me that doc/tag
  >>> parsers should be generics. A package might want to document and parse
  >>> the roxy-doc of it's objects in a class dependent way. So why not to use
  >>> the native S4 mechanism?
  >> 
  >> See the doctype, object_from_call, usage and default_exports generics.

Ok, I looked into it. 

It's still the pseudo dispatch on textual representation of the object
definition. That is you parse the "foo <- function(" and dispatch
(object_from_call) on "function", setGeneric(foo) is dispatched on
"setGeneric" etc. 

Wouldn't it be better to inspect the evaluation environment for the
traces of the evaluation and then dispatch on the objects discovered?
Then the code

aaa <- local({ ... compute object ..})

will correctly dispatch on aaa and won't be ignored. 

It will be possible to create documentation for a bunch of objects at
the same time. For example

local({ a <- generate_object_a()
        b <- generate_object_b()})

will document both a and b.


  >> I don't see the need for every tag to be class aware just a few.

This is a complication. You ending up in implementing your own OO
system. For example,  from roccer-.r:

     #' The roccer object is a key component in roxygen3 - it defines the behaviour
     #' of a tag with a \code{parser} and a \code{output} write.
       
Why would you need an roccer if you already have "classes" and "methods"
to define the behavior of the tag?

You can just have a virtual S4 class "roxy_tag". Then subclass
"roxy_tag_oxygen" and have all other tags derive from that. Most of them
will probably have only two slots, "name" and "text", but some like
"slots" tag will have more.

Then you can have "roxy_split_oxigen(object, doc)" generic dispatched on
object which would split the string 'doc' into tags. Each tag is an
object.  Then another generic "roxy_parse(tag)" to actually parse the
tag. Another generic "roxy_rd(tag)" to generate rd entry, and yet
another generic "roxy_template(tag)" to generate template. And so on.

The end user can getClass("roxy_tag") to see all the tags which
are available. Same applies to methods.

To add a markdown syntax or whatever, you can just define
"roxy_tag_markdown" class for tags, and add corresponding methods
"roxy_parse", "roxy_split_markdown" etc

All of this looks simple, consistent and transparent to me. In order to
extend roxygen, one would not need to dig into the code and learn how it
works and try to find workarounds to implement features which are not
there. But, instead, just start writing methods and classes directly.

  >> 
  >>> Also would be good to have a roc_template generic, which would generate
  >>> a bare-bone documentation of an object. This is for editors to be able
  >>> to quickly insert a roxygen template based on the object at the cursor
  >>> and its class.
  >> 
  >> Can you give an example?  Generally, if you can automatically generate
  >> the template, why can't you automatically generate the Rd directly?
  >> 

What I meant here is the following. Suppose you have a function
declaration:

     foo <- function(a = 4, b = 34){
       a + b
     }

To start documenting the function, a user might want to insert a
skeleton for a documentation (template) like following 
     
     ##' ..description
     ##'
     ##' @title 
     ##' @param a 
     ##' @param b 
     ##' @return 
     ##' @author User Name
     ##' @examples 
     
Depending on the editor, this might be bound to a key. 

There might be also a roxy_update(OBJECT, OLD_TEXT) method which would
take OLD_TEXT and output a modified version of it to account for changes
in OBJECT. For example, if you have documented parameters a and b above,
and then decided to rename b into c, then roxy_update will just change
@param b into @param c. An editor can bind this to a key. 

       Vitalie


More information about the Roxygen-devel mailing list