[Roxygen-devel] Proposal for help operator for reference class methods

Hadley Wickham h.wickham at gmail.com
Wed Jan 29 16:28:26 CET 2014


Hi all,

The code below implements a proposal for adding support for reference
class methods to ?.  If you think it looks reasonable, I'll forward on
to Duncan Murdoch for further review, and hopefully inclusion in base
R.  The logic is rather complicated because of the many possible
inputs, but basically:

* If there's a help topic with alias class$method it will be shown
* Otherwise show the doc string.

Hadley


rc_help <- function(call, where = parent.frame()) {
  call <- substitute(call)

  if (!identical(call[[1]], quote(`$`))) {
    stop("Not a RC method call")
    # In real help code this would happen elsewhere
  }

  stopifnot(is.name(call[[2]]), is.name(call[[3]]))
  class <- as.character(call[[2]])
  method <- as.character(call[[3]])

  # Figure out whether class is the name of a class or an object
  # This is complicated by the fact that the generator functions have
  # the same name as the class and are RC objects.
  is_class <- isClass(class, where = where)
  if (is_class) {
    classDef <- getClass(class, where = where)

    # Check it's a ref class
    if (!is(classDef, "refClassRepresentation")) {
      stop(class, " is not a reference class")
    }
    class_obj <- getRefClass(class)
  } else  {
    # Must be an object
    if (!exists(class, envir = where)) {
      stop(class, " is not a class or an object")
    }
    obj <- get(class, envir = where)

    # Must be a reference lass
    if (!is(obj, "refClass")) {
      stop(class, " is not a reference class")
    }

    class <- class(obj)
    class_obj <- obj$getRefClass()
  }

  # Check that method is method of class
  if (!(method %in% class_obj$methods())) {
    stop(method, " not a method of ", class)
  }

  # Try rd file if available
  alias <- paste0(class, "$", method)
  topic <- help(alias)

  if (length(topic) > 0) {
    print(topic)
  } else {
    # No Rd file found, use docstring
    # Construct call to help, because it uses non-standard evaluation
    call <- substitute(class_obj$help(method), list(method = method))
    eval(call)
  }

}

ClassA <- setRefClass("ClassA", methods = list(
  f = function() {
    "Some documentation"
  }
))
ObjA <- ClassA()

ClassB <- setClass("ClassB", contains = "list")
ObjB <- ClassB()

if (FALSE) {

  rc_help(ClassA$f)
  rc_help(ObjA$f)

  # Should fail: not reference classs
  rc_help(ClassB$f)
  rc_help(ObjB$f)

  # Should fail: doesn't exist
  rc_help(ClassC$f)
  rc_help(ClassA$g)
  rc_help(ObjA$g)
}


-- 
http://had.co.nz/


More information about the Roxygen-devel mailing list