-
Notifications
You must be signed in to change notification settings - Fork 56
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
R6 equivalent to the python __call__ dunder method #220
Comments
I'm pretty sure that in R, using library(R6)
Foo <- R6Class("Foo",
public = list(
call = function() {
self$x
},
x = 10,
printx = function() {
cat("The value of x is", self$x)
}
)
)
foo <- function() {
obj <- Foo$new()
# Return the obj$call method, and attach the full object as an attribute named
# 'impl'. Also add the class "wrapped" to it so that we can define `$` and
# `$<-` methods for it.
structure(
obj$call,
impl = obj,
class = "wrapped"
)
}
# The $ and $<- methods essentially pass through to the "impl" object attached
# to the function.
`$.wrapped` <- function(x, name) {
obj <- attr(x, "impl", exact = TRUE)
obj[[name]]
}
`$<-.wrapped` <- function(x, name, value) {
obj <- attr(x, "impl", exact = TRUE)
obj[[name]] <- value
x
}
f <- foo()
f()
#> [1] 10
f$printx()
#> The value of x is 10
f$x
#> [1] 10
f$x <- 20
f()
#> [1] 20
f$printx()
#> The value of x is 20 |
The dunder call method felt very un- |
I guess the downside is the lack of auto-complete help for internal functions ( |
You can add autocompletion with this: .DollarNames.wrapped <- function(x, pattern) {
ls(attr(x, "impl", exact = TRUE))
} |
Errr, wow. That's amazing. Very cool. |
Hi @wch, I've got another weird question that you may be able to solve. But this one is especially odd. Similar to the above questions related to having an object that looks and feels like a normal object, but has some encapsulated methods. I was wondering if it is possible to have the global object update when the value it is based on is updated in the R6 instance? This is perhaps a bit confusing so here is an example.
library(R6)
Foo <- R6Class(
"Foo",
public = list(
x = 10,
update = function(value) {
self$x <- value
}
)
)
foo <- function() {
obj <- Foo$new()
structure(
obj$x,
impl = obj,
class = "wrapped"
)
}
`$.wrapped` <- function(x, name) {
obj <- attr(x, "impl", exact = TRUE)
obj[[name]]
}
`$<-.wrapped` <- function(x, name, value) {
obj <- attr(x, "impl", exact = TRUE)
obj[[name]] <- value
obj$x
}
.DollarNames.wrapped <- function(x, pattern) {
ls(attr(x, "impl", exact = TRUE))
}
x <- foo()
x
#> [1] 10
#> attr(,"impl")
#> <Foo>
#> Public:
#> clone: function (deep = FALSE)
#> update: function (value)
#> x: 10
#> attr(,"class")
#> [1] "wrapped"
x$update(20)
x
#> [1] 10
#> attr(,"impl")
#> <Foo>
#> Public:
#> clone: function (deep = FALSE)
#> update: function (value)
#> x: 20
#> attr(,"class")
#> [1] "wrapped" |
I guess it can be summarized as modification-in-place, but in a situation where we want the object to look and feel like a familiar and common |
Hi @wch,
Is there any
R6
equivalent to the__call__
dunder method inpython
which essentially makes the class instance callable like a function? Is this a possible feature that could be added? Would there be any interest in this feature?Something like:
Pretty much all other dunder methods can be implemented in
R
by writingS3
methods for existing generics, but this one seems like it would need to be handled internally byR6
, if it's possible at all.The text was updated successfully, but these errors were encountered: