Reputation: 1470
This is not just a coding style question. If you know python (and I think also Ruby has something like this), you can have a docstring in a function, such that you can readily get that string by issuing a "help" command. e.g.:
def something(t=None):
'''Do something, perhaps to t
t : a thing
You may not want to do this
'''
if t is not None:
return t ** 2
else:
return 'Or maybe not'
Then help(something)
returns the following:
Help on function something in module __main__:
something(t=None)
Do something, perhaps to t
t : a thing
You may not want to do this
The way things work in R, you can get the full text of the defined code snippet, so you could see comments (including those at the beginning of the function), but that can be a lot of scrolling and visual filtering. Is there any better way?
Upvotes: 37
Views: 16790
Reputation: 61983
I recently wrote a package to do just this task. The docstring package allows one to write their documentation as roxygen style comments within the function they are documenting. For example one could do
square <- function(x){
#' Square a number
return(x^2)
}
and then to view the documentation either call the docstring function
docstring(square)
or use the built in ?
support and do
?square
The comments can either be a single chunk like shown above or fully roxygen style to take advantage of some of the keywords provided
square <- function(x){
#' Square a number
#'
#' Calculates the square of the input
#'
#' @param x the input to be squared
return(x^2)
}
This is on CRAN now: https://cran.r-project.org/package=docstring so you can just install using
install.packages("docstring")
or if you want the latest development version you can install from github:
library(devtools)
install_github("dasonk/docstring")
Upvotes: 26
Reputation: 368579
Sort-of -- look at the roxygen2 package on CRAN (vignette here). You write a declarative header, and among other things a help page is created for you when you 'roxygen-ize' your sources.
It may not be the easiest package to use, see here on SO for questions pertaining to it as well as its mailing list. But it probably is the closest match.
Upvotes: 11
Reputation:
RStudio helps you to create documentation quite easily. See their documentation for more information.
Upvotes: 9
Reputation: 1470
I had another idea as I'm finally wrapping my head around the fact that "R is a (very poor) LISP". Specifically, you can get access to the source code (usually) using the deparse command. So, this function would be a start towards defining your own custom source-code parsing help function:
docstr <- function(my.fun) {
# Comments are not retained
# So, we can put extra stuff here we don't want
# our docstr users to see
'This is a docstring that will be printed with extra whitespace and quotes'
orig.code.ish <- deparse(my.fun)
print(orig.code.ish[3])
}
docstr(docstr)
The above illustrates that deparse really does deparse, and is different from what you'd print at the REPL prompt if you typed docstr: quotes are changed to (default) double-quotes, opening curly brace gets moved to the second line, and blank lines (including comments) are removed. This actually helps a lot if you want to design a robust function. Would be trivial to look for e.g., opening and closing quotes down through the first line that doesn't start with a quote.
Another way to do it would be to get the list of call objects that make up the body list with body(docstr)
. The string would be in body(docstr)[[2]]
. I have to admit that I'm a bit out of my depth here, as I don't fully understand the return value of body
, and don't know where to find documentation! In particular, note that body(docstr)[2]
returns an object of type and mode 'call'.
This latter approach seems much more LISPy. I'd love to hear other's thoughts on the general idea, or have pointers to actual language reference materials for this!
Upvotes: 4
Reputation: 29447
You can add any attributes
you like to R objects, including function. So something like
describe <- function(obj) attr(obj, "help")
foo <- function(t=NULL) ifelse(!is.null(t), t^2, "Or maybe not")
attr(foo, "help") <- "Here is the help message"
produces more or less the desired output
> foo(2)
[1] 4
> foo()
[1] "Or maybe not"
> describe(foo)
[1] "Here is the help message"
Upvotes: 12
Reputation: 5700
The new reference class system has something very similar to docstrings for documenting methods of a class. Here is an example:
Something <- setRefClass("Something",
methods=list(
something=function(t=NULL) {
"Do something, perhaps to t
t : a thing
You may not want to do this
"
if(!is.null(t))
t^2
else
"Or maybe not"
}
))
a <- Something$new()
a$something(2)
a$something()
Something$help("something") ## to see help page
Upvotes: 3