Reputation: 652
I need to allow the user to create an object with one of several classes. The object will require further analysis so will be passed to one of numerous S3 methods downstream.
My thought is to have them provide the class as a character string on the creation function call, but I'm not sure the best way to use useMethod to select the proper S3 method, since the different objects will be created with different algorithms.
The create_thing() function will return an object with class set, so graph_thing() and report_thing() will take the output of create_thing() and have a class to work with.
create_thing <- function(model = 'strange', foo, bar){
tmp <- ""
class(tmp)<-model
UseMethod("create_thing", tmp)
}
create_thing.strange <- function(model, foo = 1, bar = 2){
## stuff
print("strange")
return(structure(list(data=runif(5)), class = c("list", "strange")))
}
create_thing.normal <- function(model, foo = 3, bar = 4){
## stuff
print("normal")
return(structure(list(data=rnorm(5)), class = c("list", "normal")))
}
graph_thing <- function(athing){
UseMethod("graph_thing")
}
graph_thing.normal <- function(athing){
print("normal")
plot(athing$data)
}
graph_thing.strange <- function(athing){
print("strange")
plot(athing$data)
}
report_thing <- function(athing){
UseMethod("report_thing")
}
report_thing.normal <- function(athing){
print("normal")
print(mean(athing$data))
}
report_thing.strange <- function(athing){
print("strange")
print(median(athing$data))
}
Upvotes: 1
Views: 81
Reputation: 206232
The UseMethod
function looks up the call stack to see what was passed in to the original function. Any modifications or new objects created will not influence how dispatching works.
If you are using the create_thing
functions to initilize the object, then you should create a separate generic function for that
create_thing <- function(model = 'strange', foo, bar){
tmp <- ""
class(tmp)<-model
init_thing(tmp, foo, bar)
}
init_thing <- function(model, foo=0, bar=0) {
UseMethod("init_thing")
}
init_thing.strange <- function(model, foo = 1, bar = 2){
## stuff
print("strange")
return(structure(list(data=runif(5)), class = c("list", "strange")))
}
init_thing.normal <- function(model, foo = 3, bar = 4){
## stuff
print("normal")
return(structure(list(data=rnorm(5)), class = c("list", "normal")))
}
Upvotes: 1