I was looking at some code earlier today (https://www.r-bloggers.com/building-your-own-blockchain-in-r/) where someone was defining S3 functions in a way that I'd never seen before and liked the visual style, but have never seen it anywhere else in R code and wanted to figure out why.
They defined a number of S3 classes that looked like
my_class <- function(){
# set some attributes
inst <- list(foo = "bar")
# define a function
inst$change_foo <- function(what) {inst$foo <- what}
# get S3 class right
class(inst) <- "my_class"
inst <- list2env(inst)
inst
}
Basically, it strikes me that this person was trying to make R's generic-function S3 OO system look like the more standard message-passing OO system (a la Python, Java, etc) where methods belong to classes.
My sense is that this is probably bad practice in R, since
baz <- my_class()
baz$change_foo("baz")
doesn't really do what you think it does. My, admittedly thin, understanding is that in other object oriented languages, baz$change_foo
is actually bound to that instance of my_class
, so it will always edit baz
.
In R, that binding doesn't actually happen, and so the inst
in the my_class
definition could find a different inst
than baz
if it happens to be in the environment.
It's only that list2env
call that keeps things tidy here, and that could get messed up in a more complicated example.
I do like the way this code visually encapsulates functions for my_class
, so I'm curious if I'm onto something here, or if I'm getting all worked up over nothing. Denizens of Stack Overflow, what say you? Is this good style or bad?