Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ S3method("[<-",S7_object)
S3method("[[",S7_object)
S3method("[[<-",S7_object)
S3method("|",S7_class)
S3method(Complex,S7_object)
S3method(Math,S7_object)
S3method(Ops,S7_object)
S3method(Summary,S7_object)
S3method(c,S7_class)
S3method(print,S7_S3_class)
S3method(print,S7_any)
Expand Down
40 changes: 40 additions & 0 deletions R/method-group.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
group_generic_Math <- NULL
group_generic_Ops <- NULL
group_generic_Complex <- NULL
group_generic_Sumary <- NULL

on_load_define_group_generics <- function() {
group_generic_Math <<- new_generic("Math", "x")
group_generic_Ops <<- new_generic("Ops", c("e1", "e2"))
group_generic_Complex <<- new_generic("Complex", "z")
group_generic_Summary <<- new_generic("Summary", "x", function(x, ..., na.rm = FALSE) {
S7_dispatch()
})
}

#' @export
Math.S7_object <- function(x, ...) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you also need to check for a "specific" generic call here?

group_generic_Math(x, ..., .Generic = .Generic)
}

#' @export
Ops.S7_object <- function(e1, e2) {
Comment thread
hadley marked this conversation as resolved.
Outdated
dispatch <- list(obj_dispatch(e1), obj_dispatch(e2))
specific <- .Call(method_, base_ops[[.Generic]], dispatch, environment(), FALSE)

if (!is.null(specific)) {
specific(e1, e2)
} else {
group_generic_Ops(e1, e2, .Generic = match.fun(.Generic))
}
}

#' @export
Complex.S7_object <- function(z) {
group_generic_Complex(z, .Generic = .Generic)
}

#' @export
Summary.S7_object <- function(..., na.rm = FALSE, .Generic) {
group_generic_Summary(..., na.rm = TRUE, .Generic = .Generic)
}
5 changes: 0 additions & 5 deletions R/method-ops.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ on_load_define_ops <- function() {
)
}

#' @export
Ops.S7_object <- function(e1, e2) {
base_ops[[.Generic]](e1, e2)
}

#' @rawNamespace if (getRversion() >= "4.3.0") S3method(chooseOpsMethod, S7_object)
chooseOpsMethod.S7_object <- function(x, y, mx, my, cl, reverse) TRUE

Expand Down
1 change: 1 addition & 0 deletions R/zzz.R
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ methods::setOldClass(c("S7_method", "function", "S7_object"))

.onLoad <- function(...) {
on_load_make_convert_generic()
on_load_define_group_generics()
on_load_define_matrixOps()
on_load_define_ops()
on_load_define_or_methods()
Expand Down
14 changes: 14 additions & 0 deletions tests/testthat/test-method-group.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
test_that("specific method overrides group generic", {
foo <- new_class("foo", class_integer)

method(`+`, list(foo, foo)) <- function(e1, e2) {
foo(S7_data(e1) + S7_data(e2) + 100L)
}
method(group_generic_Ops, list(foo, foo)) <- function(e1, e2, .Generic) {
foo(.Generic(S7_data(e1), S7_data(e2)))
}

expect_equal(foo(1L) * foo(1:5), foo(1:5))
expect_equal(foo(1L) + foo(1:5), foo(1:5 + 101L))

})