๐ŸŽ“ A1Learner
๐Ÿ”
0 of 27 lessons completed

R S3 Inspection

Inspection tools report the methods a script has defined for a generic. methods() lists them and getS3method() fetches one by name.

List the methods of a generic

The script defines two methods for describe. methods prints both names in one vector, with a hint line under it.

describe <- function(x, ...) {
  UseMethod("describe")
}
describe.wallet <- function(x, ...) {
  cat("A wallet holding", x$balance, "coins\n")
}
describe.savings <- function(x, ...) {
  cat("A savings pot holding", x$balance, "coins\n")
}
print(methods("describe"))

A shorter list for one method

This script defines only the wallet method. The list holds one name and length counts one item in the returned vector.

describe <- function(x, ...) {
  UseMethod("describe")
}
describe.wallet <- function(x, ...) {
  cat("A wallet holding", x$balance, "coins\n")
}
print(methods("describe"))
found <- methods("describe")
print(length(found))

Fetch one method and call it

getS3method fetches the wallet method by name. Calling the fetched value on the wallet runs that method.

describe <- function(x, ...) {
  UseMethod("describe")
}
describe.wallet <- function(x, ...) {
  cat("A wallet holding", x$balance, "coins\n")
}
describe.savings <- function(x, ...) {
  cat("A savings pot holding", x$balance, "coins\n")
}
w <- structure(list(balance = 50), class = "wallet")
fn <- getS3method("describe", "wallet")
fn(w)

A fetched method stays fixed

Both methods are fetched and then called on the same savings value. The wallet method still prints its own line, because the pick was made when it was fetched.

describe <- function(x, ...) {
  UseMethod("describe")
}
describe.wallet <- function(x, ...) {
  cat("A wallet holding", x$balance, "coins\n")
}
describe.savings <- function(x, ...) {
  cat("A savings pot holding", x$balance, "coins\n")
}
s <- structure(list(balance = 80), class = "savings")
wallet_method <- getS3method("describe", "wallet")
savings_method <- getS3method("describe", "savings")
wallet_method(s)
savings_method(s)

Example

describe <- function(x, ...) {
  UseMethod("describe")
}
describe.wallet <- function(x, ...) {
  cat("A wallet holding", x$balance, "coins\n")
}
describe.savings <- function(x, ...) {
  cat("A savings pot holding", x$balance, "coins\n")
}
print(methods("describe"))
w <- structure(list(balance = 50), class = "wallet")
s <- structure(list(balance = 80), class = "savings")
fn <- getS3method("describe", "savings")
fn(s)
describe(w)

Key points

  • methods() takes the generic name as text and returns the method names as a character vector.
  • A second printed line points to the help page for methods.
  • getS3method() takes the generic name and the class name, both as text.
  • The value it returns is the method itself, so calling it runs the method.
  • Once fetched, a method is fixed and calling it on another class still runs that same method.

In this example, methods lists the two describe methods the script defined. getS3method then fetches the savings method and calls it, while the last line shows the generic still picking the wallet method on its own.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท rdrr.io R Snippets

Exercise

What does getS3method("describe", "wallet") return?