r-lib / R6

Encapsulated object-oriented programming for R
https://R6.r-lib.org
Other
407 stars 56 forks source link

calling default print.R6 evaluates a function in active binding #58

Closed osofr closed 9 years ago

osofr commented 9 years ago

Calling print on R6 class with no custom print field can have unintended side-effects in the presence of active bindings. Namely, calling print.R6 results in a call to an active binding. Presumably this side effect is due to the following line in print.R6, but I could be wrong:

if (is.function(x$print)) {

Here is working example:

DatNet <- R6Class(classname = "DatNet",
  portable = TRUE,
  class = TRUE,
  public = list(
    names.netVar = character(), 
    dat.netVar = NULL,
    nobs = NA_integer_,        # n of samples in the OBSERVED (original) data
    initialize = function(...) {
      self$nobs <- 5
      self$names.netVar <- c("a", "b", "c")
      self$dat.netVar <- matrix(rnorm(self$nobs*self$netVarcols), nrow = self$nobs, ncol = self$netVarcols)
      invisible(self)
    }
  ),
  active = list(
    netVarcols = function() { length(self$names.netVar) },
    emptydat.netVar = function() {
      self$dat.netVar <- NULL
    }
  ),
  private = list(
    placeholder = list()
  )
)

Calling print on the above class results in a call to active binding emptydat.netVar. Declaring custom print method resolves the issue.

> obj1 <- DatNet$new()
> obj1$dat.netVar
          [,1]        [,2]        [,3]
[1,] -0.269372  0.79446229  0.98175475
[2,]  1.133334 -1.32574714 -1.20282831
[3,] -2.368485  0.95973746 -1.78660919
[4,]  1.170917  0.02439178  0.02168259
[5,] -1.232807 -0.52719650  1.26407477
> obj1
<DatNet>
  Public:
    dat.netVar: -0.269371987182663 1.13333408125977 -2.36848479502333 1. ...
    emptydat.netVar: active binding
    initialize: function
    names.netVar: a b c
    netVarcols: active binding
    nobs: 5

> 
> obj1$dat.netVar
NULL
> obj1
<DatNet>
  Public:
    dat.netVar: 
    emptydat.netVar: active binding
    initialize: function
    names.netVar: a b c
    netVarcols: active binding
    nobs: 5
gaborcsardi commented 9 years ago

Wasn't this fixed in #38? See also #37.

osofr commented 9 years ago

You are right, my bad, I wasn't using the github version of R6. Thanks for pointing it out!