`vec_arith` double dispatch error with packages

328 Views Asked by At

I'm trying to implement the vctrs package, but specifically I'm trying to get the vec_arith double dispatch working.

The example code below works if I load this into the global environment, however it does not seem to find the correct dispatch if calling from within its own package namespace.

#' @import vctrs
NULL

#' @export
foo <- function(x = double()) new_vctr(x, class = "Foo")

#' @export
vec_arith.Foo <- function(op, x, y, ...){
  UseMethod("vec_arith.Foo", y)
}

#' @export
vec_arith.Foo.default <- function(op, x, y, ...){
  stop_incompatible_op(op, x, y)
}

#' @export
vec_arith.Foo.Foo <- function(op, x, y, ...) {
  switch(op,
         "+" = foo(vec_data(x)+vec_data(y)),
         stop_incompatible_op(op, x, y))
}

# After build

library(foo)
foo(1) + foo(2)
#Error in UseMethod("vec_arith.Foo", y) : 
#  no applicable method for 'vec_arith.Foo' applied to an object of class "c('Foo',     'vctrs_vctr')"
foo(1) + 2
#Error in UseMethod("vec_arith.Foo", y) : 
#  no applicable method for 'vec_arith.Foo' applied to an object of class "c('double', 'numeric')"
2 + foo(1)
#Error: <double> + <Foo> is not permitted
#Run `rlang::last_error()` to see where the error occurred.

Could someone please let me know if this is reproducible if you build a package with just this file?

I don't know if its important but the description file looks like this:

Package: foo
Type: Package
Title: What the Package Does (Title Case)
Version: 0.1.0
Author: Who wrote it
Maintainer: The package maintainer <[email protected]>
Description: More about what it does (maybe more than one line)
    Use four spaces when indenting paragraphs within the Description.
License: What license is it under?
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.1
Imports:
  vctrs
Roxygen: list(markdown = TRUE)
1

There are 1 best solutions below

0
On

I figured it out...

at the very minimum you would need to include the following documentation with roxygen2 in order for the S3 method to export correctly

#' @method vec_arith.Foo Foo
#' @export
vec_arith.Foo.Foo <- function(op, x, y, ...) {
  switch(op,
         "+" = foo(vec_data(x)+vec_data(y)),
         stop_incompatible_op(op, x, y))
}