[Rd] [R-pkg-devel] Three-argument S3method declaration does not seem to affect dispatching from inside the package.

Iñaki Ucar |uc@r @end|ng |rom |edor@project@org
Sun May 19 16:59:07 CEST 2019


On Sat, 18 May 2019 at 23:34, Pavel Krivitsky <pavel using 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



More information about the R-devel mailing list