klmr / box

Write reusable, composable and modular R code
https://klmr.me/box/
MIT License
833 stars 47 forks source link

Limitations to documenting modules? #255

Closed mbojan closed 1 year ago

mbojan commented 2 years ago

Error description

I'm test-driving box (1.1.0) currently, and I'm pretty happy with it so far (thanks!). I have developed a module and try to document the functions in the same way one does it when developing a package. I believe I run into some undocumented limitations to how the module documentation is handled (are there any?). When calling box::help() I'm getting:

box::use(
  fun.validity = codebox/validity[...]
)
box::help("check_validity") # Shouldn't that work? check_validity() is exported from module codebox/validity
## Error in topic[[2L]] : subscript out of bounds

# This works (help page is displayed in RStudio), but with messages
box::help(fun.validity$check_validity)

## REDIRECT:topic    check_validity -> Rtxt287041ab177b [ FAIL ]
## REDIRECT:topic    check_validity.aphrodito_parsed_metadata -> Rtxt287041ab177b [ FAIL ]
## REDIRECT:topic    check_validity.aphrodito_parsed_node -> Rtxt287041ab177b [ FAIL ]
## REDIRECT:topic    check_validity.aphrodito_parsed_nodes -> Rtxt287041ab177b [ FAIL ]
## REDIRECT:topic    check_validity.aphrodito_parsed_document -> Rtxt287041ab177b [ FAIL ]
## REDIRECT:file     Rtxt287041ab177b -> Rtxt287041ab177b [ FAIL ]Warning message:
## In file(file, ifelse(append, "a", "w")) :
##   cannot open file 'C:/Users/MBOJAN~1/AppData/Local/Temp/help/Rtxt287041ab177b': No such file or directory

The documentation uses @describeIn to collect documentation of check_validity() generic and its methods, which seem to work correctly (section "Methods" is properly generated). The redirect warnings seem to be related to cross-references, which I did not explicitly create. The last REDIRECT:file warning is generated by one explicit reference to a documentation of a function in the same module.

I'm not sure if the above are bugs (should work but don't), missing documentation (there are limits to how box::help() works at this moment) or a feature request (it doesn't work now but would be great to have in the future)... ;-) It would be nice to give a head's up in ?box::help that some features of Roxygen may be / are not available (if this is the case).

R version

platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          4                           
minor          1.1                         
year           2021                        
month          08                          
day            10                          
svn rev        80725                       
language       R                           
version.string R version 4.1.1 (2021-08-10)
nickname       Kick Things                

‘box’ version

1.1.0

mbojan commented 2 years ago

For the sake reproducibility use the following module file:

#' This is a generic function
#' 
#' @param x an argument
#' @param ... dots
#' 
#' @seealso A link to base function: \code{\link{plot}}. A link to another
#'   function in the module: \code{\link{another_function}}.
#' 
#' @export
#' 
generic_function <- function(x, ...) UseMethod("generic_function")

#' @describeIn generic_function Paste "foo"
generic_function.foo <- function(x, ...) paste("foo", x)

#' @describeIn generic_function Paste "bar"
generic_function.bar <- function(x, ...) paste("bar", x)

#' This is another function
#' 
#' @return Bang!
#' 
#' @export
another_function <- function() "bang!"

Assuming the above is saved in codebox/module.R I'm getting (didn't work with reprex):

> box::use(m=codebox/module) # Don't attach
> box::help("generic_function")
Error in topic[[2L]] : subscript out of bounds
> box::help(m$generic_function) # works with warnings
Loading required namespace: roxygen2

REDIRECT:topic   generic_function -> Rtxt2bc821ab2a7e [ FAIL ]
REDIRECT:topic   generic_function.foo -> Rtxt2bc821ab2a7e [ FAIL ]
REDIRECT:topic   generic_function.bar -> Rtxt2bc821ab2a7e [ FAIL ]
REDIRECT:file    Rtxt2bc821ab2a7e -> Rtxt2bc821ab2a7e [ FAIL ]Warning message:
In file(file, ifelse(append, "a", "w")) :
  cannot open file 'C:/Users/MBOJAN~1/AppData/Local/Temp/help/Rtxt2bc821ab2a7e': No such file or directory
> box::unload(m)
> 
> 
> box::use(m=codebox/module[...]) # Attach
> box::help("generic_function")
Error in topic[[2L]] : subscript out of bounds
> box::help(m$generic_function) # works with warnings

REDIRECT:topic   generic_function -> Rtxt2bc8539a728 [ FAIL ]
REDIRECT:topic   generic_function.foo -> Rtxt2bc8539a728 [ FAIL ]
REDIRECT:topic   generic_function.bar -> Rtxt2bc8539a728 [ FAIL ]
REDIRECT:file    Rtxt2bc8539a728 -> Rtxt2bc8539a728 [ FAIL ]Warning message:
In file(file, ifelse(append, "a", "w")) :
  cannot open file 'C:/Users/MBOJAN~1/AppData/Local/Temp/help/Rtxt2bc8539a728': No such file or directory
> box::unload(m)

The links in See also are not functional.

klmr commented 2 years ago

Thanks for the bug report. There are several things happening here, I hope the following list is complete:

The error

> box::help("generic_function")
Error in topic[[2L]] : subscript out of bounds

This is the expected behaviour: in contrast to many base R functions, ‘box’ is strongly typed and does not permit using character strings in place of syntactic names. To show the help for a name, it must be passed unquoted:

box::help(generic_function)

The warnings

This is a bug in ‘box’, caused by a change in R 4.1.0. I have implemented a candidate fix that removes the warning messages, which I’ll push shortly.

Links in documentation

Unfortunately that’s currently missing from ‘box’, and adding it isn’t trivial because links only work in R’s “dynamic” help, and the dynamic help system makes strong assumptions about being called for packages. It fundamentally doesn’t work with anything else (including ‘box’ modules). A potential workaround would be to create a fake package file/folder hierarchy when displaying the help for a module. However, lacking documentation of these R internals doesn’t make an implementation easy. I still want to implement this at some point but I don’t know when I’ll find time for it.

mbojan commented 2 years ago

Thanks @klmr .

Ad 1. I somehow missed that, thanks.

Ad 2. I look forward to the fix.

Ad 3. I guess it would be worthwhile to mention this limitation somewhere in the documentation/vignette. I think another complication is that generating/serving the help pages is different on Windows and linuxalikes. E.g. during package installation static help pages are generated only on Windows (at least judging from the output of R CMD INSTALL). I ran into this some time ago when trying to push dynamic help pages to some limits, but I don't exactly recall right now where this is buried in the R sources.