r-lib / R6

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

Private member & method names vs public / active names #200

Closed gaow closed 4 years ago

gaow commented 4 years ago

@wch If I set a private member and an active binding with the same variable name I get the error:

  All items in public, private, and active must have unique names.

I understand that public and active should have unique names because of obvious conflict otherwise. But why private vs public / active? Because they can be uniquely identified as private$name and self$name. Currently my variable names are ugly (have to have .X for private and X for active binding for example) due to this constraint. If I start working with X as a private member then later decide to make it an active binding for access outside the class, then I'll have to change all my existing private$X to private$.X (including those in derived classes!) then define the active binding.

Such inelegancy has been the biggest hurdle for me to advocate the use of R6 among my colleagues. I'm wondering if there is a good reason for the constraint, or it can be removed. Thanks!

wch commented 4 years ago

The reason is that the original design of R6 behaved more like R's reference classes: private and public members could be accessed without private$x or self$y -- that is, with just x or y. Later on, the portable option was added, and when set to FALSE, it still has the same behavior. In these cases, it's that important to make sure there are no name collisions.

When portable=TRUE (the default), it results in the behavior you're used to, where private$ and self$ are required to access members. But even with portable=TRUE, overlapping names would cause problems when inheritance is involved. The superclass's private and public methods are combined together in the super object, so it's necessary to enforce different names to avoid collisions.

gaow commented 4 years ago

Thanks @wch for the clarification.

The superclass's private and public methods are combined together in the super object

Looks like this could be improved to overcome the limitation with portable=TRUE. Otherwise R6 is really nice -- syntactically nicer than C++ and Python's class in my opinion! I do hope down the road this constraint can be removed to make the syntax more elegant.

wch commented 4 years ago

Unfortunately, it's not possible to change that behavior without breaking a lot of existing code.