In Python, classmethods are heritable methods that can be called from the class itself MyClass.class_method() (not just from an instance of that class MyClass().normal_method()) like a staticmethod, but which also has access to cls, the class definition. This is particularly helpful for alternate ways of instantiating a class, like pd.DataFrame.from_dict().
In R6, all methods are only available after instantiation, unless they're explicitly added to the environment after class creation like
but that is effectively a non-heritable (it will not exist on any child classes) static method, not a class method that has access to the class itself. Since MyClass already exists, you could call it recursively:
...but that moves it further from heritability, since when inherited it would still point to the parent class instead of the current class.
For my own purposes (I needed a set of classes that can be serialized/deserialized to/from JSON), I created a wrapper around R6Class that stores classmethods (all in a static list for now, since any classmethod that does not reference self (really equivalent to cls here) is a staticmethod) in private$static, and then appends them to child classes when applicable:
R6Point1Class <- function(..., static = NULL) {
Class <- R6::R6Class(...)
Class$parent_env <- parent.frame()
full_static <- modifyList(
Class$get_inherit()$private_fields$static %||% list(),
static %||% list()
)
full_static <- lapply(full_static, function(x) {
if (!is.function(x)) return(x)
environment(x) <- Class
x
})
Class$set('private', 'static', full_static)
for (name in names(Class$private_fields$static)) {
Class[[name]] <- Class$private_fields$static[[name]]
}
Class
}
I'm sure this implementation has bugs and corner cases (at a minimum, it does not play nice with roxygen), but given that class methods are common in Python, maybe there is appetite for adding support directly to R6Class? https://github.com/r-lib/R6/issues/66 looks like a similar proposal for static attributes and methods; this would presumably be similarly implemented, but with an evaluation environment with access to the class definition (presumably as self or class or cls or some other reserved keyword). At a minimum, it seems to me worth a conversation!
In Python, classmethods are heritable methods that can be called from the class itself
MyClass.class_method()
(not just from an instance of that classMyClass().normal_method()
) like a staticmethod, but which also has access tocls
, the class definition. This is particularly helpful for alternate ways of instantiating a class, likepd.DataFrame.from_dict()
.In R6, all methods are only available after instantiation, unless they're explicitly added to the environment after class creation like
but that is effectively a non-heritable (it will not exist on any child classes) static method, not a class method that has access to the class itself. Since
MyClass
already exists, you could call it recursively:...but that moves it further from heritability, since when inherited it would still point to the parent class instead of the current class.
For my own purposes (I needed a set of classes that can be serialized/deserialized to/from JSON), I created a wrapper around
R6Class
that stores classmethods (all in astatic
list for now, since any classmethod that does not referenceself
(really equivalent tocls
here) is a staticmethod) inprivate$static
, and then appends them to child classes when applicable:I'm sure this implementation has bugs and corner cases (at a minimum, it does not play nice with roxygen), but given that class methods are common in Python, maybe there is appetite for adding support directly to
R6Class
? https://github.com/r-lib/R6/issues/66 looks like a similar proposal for static attributes and methods; this would presumably be similarly implemented, but with an evaluation environment with access to the class definition (presumably asself
orclass
orcls
or some other reserved keyword). At a minimum, it seems to me worth a conversation!