[Roxygen-devel] S4 implementation of @usage
Hadley Wickham
hadley at rice.edu
Thu Aug 30 15:57:41 CEST 2012
> I have done my best here https://gist.github.com/3516476
Thanks - that's useful. A few comments/questions:
* I don't think the spec for processTag is quite right yet - currently
you have it returning a transformed object of the same class as the
input - but that only works for a limited number of tags. Many tags
also need to modify other tags the rocblock. For example the "@intro"
tag (a virtual tag added to the start of every rocblock) needs to
modify the title, description and details. The @docType tag needs to
modify a lot of other pieces.
It would be possible to rewrite them to "pull" rather than "push",
i.e. so that @title would check @intro, and @keywords would check
@docType but I don't think that's as good a design as it means the
code for one tag needs to be put in multiple places.
* Similarly, I still don't see how tags that operate globally would
work. I think that's partly because the model is so focussed on the
individual tag - the tag classes become very heavy - that's where all
the logic is stored. That's not such a good fit for actions that work
on multiple tags in multiple rocblocks. I wonder if we need a
alternative model for some tags - instead of being stored in each
rocblock, they should be stored globally:
setClass("GlobalTag", contains = "Tag",
slots = "RocBlock" # pointer back to the rocblock that contained them
)
setClass("FamilyTag", contains = "GlobalTag")
setClass("IncludeTag", contains = "GlobalTag")
setClass("InheritParamsTag", contains = "GlobalTag")
# Takes list of tags as input (not sure how dispatch would work) and
rocBlocks as input
# Returns list of rocblocks as output
setGeneric("processGlobalTags")
* I think I need to explain the output model a little bit more - the
output needs to be by tag, and return an intermediate representation
of the output object. More like:
setGeneric("outRd")
setMethod("outRd", "roxyTag", function(tag, rocblock)) {
filename <- getTag(rocblock, "rdname")
rdCommand(tag at name, tag at value, path = filename)
}
This is because the output methods can't write directly to disk - they
may need to do some aggregation:
* multiple rocblocks may output to the same Rd file with @rdname
* all outputs to NAMESPACE need to be sorted and have duplicates removed.
Another possible approach could be:
setClass("OutputRd")
setGeneric("makeOutput", function(input, output) {})
setMethod("makeOutput", c("TagParam", "OutputRd"), ...)
setMethod("makeOutput", c("TagImport", "OutputNamespace"), ...)
setMethod("makeOutput", c("TagIncludes", "OutputDescription") ...)
setMethod("makeOutput", c("RoxyBlock", "Output"), function(input, output) {
lapply(input at tags, makeOutput, output = output)
}
setMethod("makeOutput", c("RoxyPackage", "Output"), function(input, ouput) {
unlist(lapply(input at blocks, makeOutput, output = output), recursive = FALSE)
}
setGeneric("writeOutput", function(output, data) {})
setMethod("writeOutput", c("outputNamespace", "list")) {
lines <- sort(unique(unlist(data)))
write_if_different(lines, "NAMESPACE")
}
That would make it easier for the user to specify which sorts of
output they want because they could just provide a list of Output
objects to roxygenise.
> > Object seems a bit awkward because it's part of the rocblock, and is
> > currently stored in a list with it's value and it's name. But I don't
> > see how you'd dispatch on it, unless you pull it out into a separate
> > argument.
>
> Yes, dispatch is on the object which is part of rocblock (maybe
> roxyBlock?). roxyParse is used only internally, so not a big deal. When
> iterating, disassembling and calling roxyParse(rblock at object), rblock at doc)
> looks fine to me.
I think it would still need to be rblock at object@value, but that's ok too.
Hadley
--
Assistant Professor
Department of Statistics / Rice University
http://had.co.nz/
More information about the Roxygen-devel
mailing list