r-lib / R6

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

It is possible to overwrite methods in R6 objects #19

Closed richfitz closed 10 years ago

richfitz commented 10 years ago

Once an R6 object has been constructed, it is possible to overwrite its methods, which seems undesirable:

Thing <- R6::R6Class("Thing",
                     public=list(
                       a=1L,
                       f=function() a))
obj <- Thing$new()
obj$f() # 1L
obj$f <- NULL # is allowed
obj$f() # Error: attempt to apply non-function

And of course, putting the method "back" doesn't work because the environment of that function is wrong:

obj$f <- function() a
obj$f() # Error: object 'a' not found

Is there any way of easily preventing this happen without sacrificing the speed goals of R6?

richfitz commented 10 years ago

Sorry - should have said: this affects the current CRAN version (1.0.1), as well as development version a1177fc49282676e4a0ab00ab7c629d783159443

wch commented 10 years ago

Yes, it probably makes sense to lock the bindings for methods when lock=TRUE. As it is, that option stops you from adding new variables, but doesn't prevent modifying existing ones.

wch commented 10 years ago

I decided that method bindings should always be locked; if users really want to modify them, they can always unlock the bindings themselves.

mmuurr commented 3 years ago

I realized this was closed 6(!) years ago ... but I'm wondering how one would "unlock the bindings themselves". I suddenly find myself in a position where I'd like to update a method after an object has been created (i.e. an update on the instance). I tried creating the generator with lock_objects = FALSE, but I'm still getting the cannot change value of locked binding for 'foo' error. Is this doable with current R6 implementation?

gaborcsardi commented 3 years ago

unlockBinding() unlocks a binding.

mmuurr commented 3 years ago

@gaborcsardi ahhhh... I hadn't thought of that base function. Thanks!