Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inheritance allows colliding public and private member names #168

Open
jayqi opened this issue Nov 11, 2018 · 0 comments
Open

Inheritance allows colliding public and private member names #168

jayqi opened this issue Nov 11, 2018 · 0 comments
Labels
feature a feature request or enhancement

Comments

@jayqi
Copy link

jayqi commented Nov 11, 2018

Normally, when you try to define public and private members in the same class with colliding names, you get an error.

MyClass <- R6::R6Class(
    "MyClass",
    public = list(
        colliding_method = function() {"A"}
    ),
    private = list(
        colliding_method = function() {"B"}
    )
)
#> Error in R6::R6Class("MyClass", public = list(colliding_method = function() {: All items in public, private, and active must have unique names.

However, this check can get bypassed when you use inheritance. See example:

MyParentClass <- R6::R6Class(
    "MyParentClass",
    public = list(
        colliding_field = "A",
        colliding_method = function() {"A"}
    )
)

MyChildClass <- R6::R6Class(
    "MyChildClass",
    inherit = MyParentClass,
    private = list(
        colliding_field = "B",
        colliding_method = function() {"B"}
    )
)

myChildObj <- MyChildClass$new()
myChildObj$colliding_field
#> [1] "A"
myChildObj$colliding_method()
#> [1] "A"
myChildObj$.__enclos_env__$private$colliding_field
#> [1] "B"
myChildObj$.__enclos_env__$private$colliding_method()
#> [1] "B"

This can be a little confusing when using super$ because you don't specify whether you want a public or private method from the superclass. It seems like what happens is that it just gives you back the first one that it finds.

MyGrandchildClass <- R6::R6Class(
    "MyGrandchildClass",
    inherit = MyChildClass,
    public = list(
        super_method = function() {super$colliding_method()}
    )
)

myGcObj <- MyGrandchildClass$new()
myGcObj$super_method()
#> [1] "B"

Collisions between public members and active bindings through inheritance will error out but not until trying to initialize an object.

MyActiveParentClass <- R6::R6Class(
    "MyActiveParentClass",
    public = list(
        colliding_name = function() {"A"}
    )
)

MyActiveChildClass <- R6::R6Class(
    "MyActiveChildClass",
    inherit = MyActiveParentClass,
    active = list(
        colliding_name = function() {"B"}
    )
)
myActiveChildObj <- MyActiveChildClass$new()
#> Error in makeActiveBinding(name, active[[name]], public_bind_env): symbol already has a regular binding

However, collisions between private members and active bindings are allowed through.

MyActiveParentClass <- R6::R6Class(
    "MyActiveParentClass",
    private = list(
        colliding_name = function() {"A"}
    )
)

MyActiveChildClass <- R6::R6Class(
    "MyActiveChildClass",
    inherit = MyActiveParentClass,
    active = list(
        colliding_name = function() {"B"}
    )
)
myActiveChildObj <- MyActiveChildClass$new()
myActiveChildObj$colliding_name
#> [1] "B"
myActiveChildObj$.__enclos_env__$private$colliding_name()
#> [1] "A"

Seeing the same for both CRAN version 2.3.0 and the current GitHub version.

Examples created on 2018-11-11 by the reprex package (v0.2.1)

@hadley hadley added the feature a feature request or enhancement label Apr 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants