Method Dispatch with UseMethod within an environment

290 Views Asked by At

I want to be able to dispatch to methods defined within an environment. This would allow me to define polymorphic methods for proto objects (proto objects in turn inherit from the environment class). E.g.:

x <- proto()
x$foo               <- function(., obj) UseMethod("foo", obj)
x$foo.list          <- function(., obj) "obj is a list!"
x$foo.data.frame    <- function(., obj) "obj is a data.frame"
x$foo.default       <- function(., obj) "obj is neither a list nor a data.frame!"

And so I can do:

> x$foo(list())
[1] "obj is a list!"

> x$foo(1)
[1] "obj is neither a list nor a data.frame!"

However, all I get now when calling x$foo is

Error in UseMethod("foo") : 
  no applicable method for 'foo' applied to an object of class "c('proto', 'environment')"

How to fix this?

1

There are 1 best solutions below

0
On

I do not know how proto works, but as for environments, it works:

x <- environment()
x$foo               <- function(obj) { UseMethod("foo", obj) } 
x$foo.list          <- function(obj) "obj is a list!"
x$foo.data.frame    <- function(obj) "obj is a data.frame"
x$foo.default       <- function(obj) "obj is neither a list nor a data.frame!"

x$foo(list())
# [1] "obj is a list!"

x$foo(iris)
# [1] "obj is a data.frame"

proto seems to override the $ operator, so you may hack it like this:

x <- proto()
assign('.foo', function(obj) { UseMethod(".foo", obj) }, envir = x)
assign('.foo.list', function(obj)  "obj is a list2!", envir = x)
assign('.foo.data.frame', function(obj)  "obj is a data.frame2!", envir = x)
x$foo <-  function(., obj) { get('.foo', envir = .)(obj) }

x$foo(list())
x$foo(iris)