Re: [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 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 __ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
[R-pkg-devel] WInbuilder and rHub updating
--- Begin Message --- HI All: I have a package I am developing that depends on a package that was just accepted and appears on CRAN. Do Winbuilder and rHub update daily, or if not, what is the usual lag for new packages to appear on the test machines. Or may generally, is there a way to query what packages are available on either or both of these? That would be the biggest help. Thanks, -Roy ** "The contents of this message do not reflect any position of the U.S. Government or NOAA." ** Roy Mendelssohn Supervisory Operations Research Analyst NOAA/NMFS Environmental Research Division Southwest Fisheries Science Center ***Note new street address*** 110 McAllister Way Santa Cruz, CA 95060 Phone: (831)-420-3666 Fax: (831) 420-3980 e-mail: roy.mendelss...@noaa.gov www: http://www.pfeg.noaa.gov/ "Old age and treachery will overcome youth and skill." "From those who have been given much, much will be expected" "the arc of the moral universe is long, but it bends toward justice" -MLK Jr. --- End Message --- __ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Re: [R-pkg-devel] Three-argument S3method declaration does not seem to affect dispatching from inside the package.
Hi, Inaki, On Sun, 2019-05-19 at 16:59 +0200, Iñaki Ucar wrote: > 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 f <- getS3method("foo","bar") f(x) # spurious warning foo.baz <- function(x) NextMethod("foo") class(x) <- c("baz","bar") foo(x) # spurious warning Believe me, I spent a lot of time trying to get this to work, and I tried even more sophisticated call stack alchemy, but people kept getting false positives and negatives. (Take a look at my attempt in the statnet.common package.) > 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. Are you sure which package defines the generic matters? I've just ran some tests with two packages and moving the generic around doesn't seem to affect things: the calling function determines whose method is used. It seems to me like there is no contradiction after all, except that I propose that the registered method should take precedence within a namespace. The only situation in which it would change R's behaviour would be when a package/namespace contains a function foo.bar() AND a NAMESPACE containing S3method(foo,bar,not.foo.bar) AND calls foo() on objects of type bar from inside the package. It is extremely unlikely to break any existing code. Best, Pavel -- Pavel Krivitsky Lecturer in Statistics National Institute of Applied Statistics Research Australia (NIASRA) School of Mathematics and Applied Statistics | Building 39C Room 154 University of Wollongong NSW 2522 Australia T +61 2 4221 3713 Web (NIASRA): http://niasra.uow.edu.au/index.html Web (Personal): http://www.krivitsky.net/research ORCID: -0002-9101-3362 NOTICE: This email is intended for the addressee named and may contain confidential information. If you are not the intended recipient, please delete it and notify the sender. Please consider the environment before printing this email. __ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Re: [R-pkg-devel] Three-argument S3method declaration does not seem to affect dispatching from inside the package.
On Sun, 19 May 2019 at 23:23, Pavel Krivitsky wrote: > > Hi, Inaki, > > On Sun, 2019-05-19 at 16:59 +0200, Iñaki Ucar wrote: > > 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 > > f <- getS3method("foo","bar") > f(x) # spurious warning > > foo.baz <- function(x) NextMethod("foo") > class(x) <- c("baz","bar") > foo(x) # spurious warning Checking the enclosing environment and whether was called through NextMethod respectively covers these cases too. > > 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. > > Are you sure which package defines the generic matters? I've just ran > some tests with two packages and moving the generic around doesn't seem > to affect things: the calling function determines whose method is used. If package A defines generic foo and package B defines method foo.bar without registering nor exporting it, then foo can't find foo.bar. > It seems to me like there is no contradiction after all, except that I > propose that the registered method should take precedence within a > namespace. > > The only situation in which it would change R's behaviour would be when > a package/namespace contains a function foo.bar() AND a NAMESPACE > containing S3method(foo,bar,not.foo.bar) AND calls foo() on objects of > type bar from inside the package. It is extremely unlikely to break any > existing code. To try to avoid changing current behaviour if foo.bar is found, R would need to check whether the enclosing environment is identical to the enclosing environment of the registered method, and in that case, give precedence to the latter (which, BTW, is exactly what you need to do to fix the first spurious warning above). And still, funny things may happen. For example, pkgA defines generic foo, exports foo.bar and registers other.foo.bar instead of foo.bar. Following your proposal, if I load pkgA and call foo for an object of class bar, other.foo.bar is called. Then I load pkgB, which registers just another method for foo.bar, and call foo again. What happens is that the registered method belongs now to pkgB, which is a different namespace, so we got different precedence, and foo.bar is called instead. Exceptions leads us to inconsistencies like this. I can't speak for R core, but I don't think that the use case is compelling enough to take that path. Iñaki __ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel