2

Following on from a similar question, I would like to be able to allow users to extend a class in my package which uses private (not export-ed) functions.

A minimal working example:

# my_package/R/Main.R
# My package:
#' @import methods MASS
PrivateFunc <- function(...) fractions(0.5)     # a private function

#' @export Main
#' @exportClass Main
Main  <- setRefClass("Main",
    methods = list(
        initialize = function(...) PrivateFunc()
    )
)

Problem is, the Main class uses functions that are not exported from my_package, such as PrivateFunc, and also fractions from package MASS which is an Import rather than a Depends.

Thus as soon as I instantiate an class that extends Main, R complains about not being able to see PrivateFunc:

library(my_package)
Child <- setRefClass("Child", contains = "Main")
Child()
# Error in .Object$initialize(...) : could not find function "PrivateFunc"

Does this mean that I am forced to export every private function used by Main? Would this not severely pollute the global namespace (precisely the reason why I use Imports over `Depends)?

So how best to fix this?

Edit: Also, there is the possibility that the user may chose to extend Main from within their own package that they are writing

Community
  • 1
  • 1
mchen
  • 9,808
  • 17
  • 72
  • 125
  • If I type this all at the command line, just as a test, the `PrivateFunc` gets called - twice - when you **define** the `Child` class. Put a `print` in with the `fractions` call and you'll see it. I don't understand R's class system sometimes... – Spacedman Aug 14 '14 at 14:33
  • @Spacedman - it is for the same reason that `Main` must not contain any mandatory parameters in the `initialize` method. Try changing `Main` to have `initialize = function(x) force(x)` -- you won't even be able to *define* `Child`, regardless of how you intend to instantiate it... – mchen Aug 14 '14 at 14:43

1 Answers1

3

This is a limitation of reference classes. I suggest checking out R6 (note that I'm the author). See the documentation links at the bottom of the project page. The upcoming version has an option called portable, which allows for cross-package inheritance without any trouble.

wch
  • 4,069
  • 2
  • 28
  • 36