I spent the last 2 days trying to define a generic function in my own environment, but somehow I do not manage to get there. First off, some code to demonstrate my issue:
# my custom environment
my_env <- new.env()
# my generic function foo
my_env$foo <- function(x, ...) {
UseMethod('foo', x)
}
my_env$foo.character <- function(x, ...) {
print(paste('I am a character!', x))
}
my_env$foo('Hello!')
This gives me the following error message: Error in UseMethod("foo", x): no applicable method for 'foo' applied to an object of class "character"
What I learned so far from the docs of UseMethod
:
To support this, UseMethod and NextMethod search for methods in two places: in the environment in which the generic function is called, and in the registration data base for the environment in which the generic is defined (typically a namespace) So as far as I understand, it searches in the global environment (where it is called) and in
my_env
, because thats where the definition of it is. But if that would be the case, I would not get the error message.
So I also tried attaching the function to the environment, after defining the generic:
# my custom environment
my_env <- new.env()
# my generic function foo
foo <- function(x, ...) {
UseMethod('foo', x)
}
foo.character <- function(x, ...) {
print(paste('I am a character!', x))
}
my_env$foo <- foo
my_env$foo('Hello!')
I also tried UseMethod
with the environment reference:
# my custom environment
my_env <- new.env()
# my generic function foo
my_env$foo <- function(x, ...) {
UseMethod('my_env$foo', x)
}
my_env$foo.character <- function(x, ...) {
print(paste('I am a character!', x))
}
my_env$foo('Hello!')
I also attached the my_env
:
# my custom environment
my_env <- new.env()
# my generic function foo
my_env$foo <- function(x, ...) {
UseMethod('foo', x)
}
my_env$foo.character <- function(x, ...) {
print(paste('I am a character!', x))
}
attach(my_env)
my_env$foo('Hello!')
But none of these changed anything for me. I didn't really find anything about this topic on the internet and I can't believe that I'm the only one trying to use environments and generics together, since it does not make any sense to use environments at all, if it can only hold "dumb" lists and variables, but no functions and it seems to work perfectly in the context of packages.
Can anyone explain to me, what I do wrong? I appreciate any constructive comments :)
Option 1: Call the generic within the environment.
with(my_env, foo('Hello!'))
#[1] "I am a character! Hello!"
Option 2: Register the method, so that it is "in the registration data base".
with(my_env,.S3method("foo", "character", "foo.character"))
my_env$foo('Hello!')
#[1] "I am a character! Hello!"