[R-pkg-devel] Three-argument S3method declaration does not seem to affect dispatching from inside the package.
On Sat, 18 May 2019 at 23:34, Pavel Krivitsky <pavel at uow.edu.au> wrote:
The issue here is that you are registering a non-standard name (.gen.formula) for that generic and then defining what would be the standard name (gen.formula) for... what purpose? IMHO, this is a bad practice and should be avoided.
The situation initially arose when I wanted to soft-deprecate calling a particular method by its full name in order to clean up the package's namespace. To use our working example, I wanted calls to gen.formula() to issue a deprecation warning, but calls to gen(formula) not to. The simplest way to do that that I could find was to create a function, say, .gen.formula() that would implement the method and declare it as the S3 export, and modify gen.formula() to issue the warning before passing on to .gen.formula(). Then, direct calls to gen.formula() would produce a warning, but gen(formula) would by pass it.
IMO the simplest way to do this is to check who the caller was:
foo <- function(x) UseMethod("foo")
foo.bar <- function(x) {
sc <- sys.call(-1)
if (is.null(sc) || sc[[1]] != "foo")
.Deprecated(msg="Calling 'foo.bar' directly is deprecated")
}
x <- 1
class(x) <- "bar"
foo(x) # silent
foo.bar(x) # a warning is issued
That is, for a call from inside a package, the order of precedence
would be as follows:
1. S3method() in that package's NAMESPACE.
2. Appropriately named function in that package (exported or
not).
3. Appropriately named function in calling environment (which
may be
GlobalEnv).
4. S3method() in other loaded packages' NAMESPACEs.
5. Appropriately named functions exported by other loaded
packages'
NAMESPACEs.
For a call from outside a package, the precedence is the same, but
1 and 2 are not relevant.
As far as I can tell, this is the current behaviour except for the
relative ordering of 1 and 2.
Nope. Current behaviour (see details in ?UseMethod) is: "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".
Can you be more specific where the sequence above contradicts the current implementation (except for swapping 1 and 2)? As far as I can tell, it's just a more concrete description of what's in the documentation.
The description in the documentation means that point 3) in your list goes always first, which automatically implies 2) if the generic is defined in the same package. I?aki