Skip to content

Commit 3d6c6d7

Browse files
authored
Alternative backward compatibility approach for user code (RConsortium#349)
Fixes RConsortium#326
1 parent 507cc9d commit 3d6c6d7

File tree

7 files changed

+36
-29
lines changed

7 files changed

+36
-29
lines changed

NAMESPACE

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ export(super)
8282
export(valid_eventually)
8383
export(valid_implicitly)
8484
export(validate)
85+
if (getRversion() < "4.3.0") export(`@`)
8586
if (getRversion() >= "4.3.0" && !is.null(asNamespace("utils")$.AtNames)) S3method(utils::.AtNames,S7_object)
86-
if (getRversion() >= "4.3.0") S3method(base::`@`, S7_object) else export("@")
87+
if (getRversion() >= "4.3.0") S3method(base::`@`, S7_object)
8788
if (getRversion() >= "4.3.0") S3method(chooseOpsMethod, S7_object)
8889
if (getRversion() >= "4.3.0") S3method(matrixOps, S7_object)
8990
if (getRversion() >= "4.3.0") S3method(nameOfClass, S7_class, S7_class_name)

NEWS.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# S7 (development version)
22

3+
* S7 provides a new automatic backward compatibility mechanism to provide
4+
a version of `@` that works in R before version 4.3 (#326).
5+
36
* Can create multimethods that dispatch on `NULL`.
47

58
# S7 0.1.1

R/compatibility.R

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Where needed, attach an environment containing @ that works with S7
2+
activate_backward_compatiblility <- function() {
3+
if (getRversion() < "4.3.0" && !"S7_at" %in% search()) {
4+
args <- list(list("@" = `@`), name = "S7_at", warn.conflicts = FALSE)
5+
do.call("attach", args)
6+
}
7+
invisible()
8+
}
9+
10+
#' @aliases @
11+
#' @usage NULL
12+
#' @rawNamespace if (getRversion() < "4.3.0") export(`@`)
13+
#' @name prop
14+
`@` <- function(object, name) {
15+
if (inherits(object, "S7_object")) {
16+
name <- as.character(substitute(name))
17+
prop(object, name)
18+
} else {
19+
name <- substitute(name)
20+
do.call(base::`@`, list(object, name))
21+
}
22+
}

R/property.R

+4-16
Original file line numberDiff line numberDiff line change
@@ -260,28 +260,16 @@ prop_label <- function(object, name) {
260260
sprintf("%s@%s", if (!is.null(object)) obj_desc(object) else "", name)
261261
}
262262

263-
#' @rdname prop
264-
#' @usage object@name
265-
#' @aliases @
266-
#' @rawNamespace if (getRversion() >= "4.3.0") S3method(base::`@`, S7_object) else export("@")
267-
`@.S7_object` <- prop
268-
269263
# Note: we need to explicitly refer to base with "base::`@`" in the
270264
# namespace directive to ensure the method is registered in the correct place.
271265
# Otherwise, loadNamespace()/registerS3method() gets confused by the
272266
# presence of a closure w/ the name of the generic (`@`) in the R7 namespace,
273267
# and incorrectly assumes that R7::`@` is the generic and registers the
274268
# method in the package namespace instead of base::.__S3MethodsTable__.
275-
276-
`@` <- function(object, name) {
277-
if (inherits(object, "S7_object")) {
278-
name <- as.character(substitute(name))
279-
prop(object, name)
280-
} else {
281-
name <- substitute(name)
282-
do.call(base::`@`, list(object, name))
283-
}
284-
}
269+
#' @usage object@name
270+
#' @rawNamespace if (getRversion() >= "4.3.0") S3method(base::`@`, S7_object)
271+
#' @name prop
272+
`@.S7_object` <- prop
285273

286274
#' @rawNamespace S3method("@<-",S7_object)
287275
`@<-.S7_object` <- function(object, name, value) {

R/zzz.R

+2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ methods::setOldClass(c("S7_method", "function", "S7_object"))
119119
}
120120

121121
.onLoad <- function(...) {
122+
activate_backward_compatiblility()
123+
122124
on_load_make_convert_generic()
123125
on_load_define_matrixOps()
124126
on_load_define_ops()

man/prop.Rd

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vignettes/packages.Rmd

+1-10
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,4 @@ Otherwise, you can conditionally make an S7-aware `@` available to your package
6565
NULL
6666
```
6767

68-
You can additionally make `@` work for users of your package by attaching the S7 package when your package is attached with this `.onAttach()` code:
69-
70-
```{r}
71-
.onAttach <- function(libname, pkgname) {
72-
if (getRversion() < "4.3.0")
73-
require(S7)
74-
}
75-
```
76-
77-
Use this technique with care as it will attach S7 to the user search path, possibly causing conflicts with other packages/functions.
68+
`@` will work for users of your package because S7 automatically attaches an environment containing the needed definition when it's loaded.

0 commit comments

Comments
 (0)