3

Function objects seems to work well with dispatching of S3 methods.
But for some reason they cannot be exported in NAMESPACE file.

Below code works with dispatching to *.function method:

as.abc = function(x, ...){
    UseMethod("as.abc")
}
as.abc.list = function(x, ...){
    stopifnot(is.list(x))
    structure(x, class="abc")
}
as.abc.function = function(x, ...){
    stopifnot(is.function(x))
    structure(x, class="abc")
}
# list
l = as.abc(list(1))
str(l)
#List of 1
# $ : num 1
# - attr(*, "class")= chr "abc"

# function
f = as.abc(function(x) x)
str(f)
#function (x)  
# - attr(*, "srcref")=Class 'srcref'  atomic [1:8] 1 12 1 24 12 24 1 1
# .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x3dbb848> 
# - attr(*, "class")= chr "abc"

But when I try to define export in NAMESPACE as:

export(as.abc)
S3method(as.abc, list)
S3method(as.abc, function)

It throws an error while R CMD check:

* checking package namespace information ... ERROR
Invalid NAMESPACE file, parsing gives:
Error in parse(nsFile, keep.source = FALSE, srcfile = NULL): 29:26: unexpected ')'
28: S3method(as.abc, list)
29: S3method(as.abc, function)

I tried also wrap into ` but it didn't help too

S3method(as.abc, `function`)

What is the proper way to export method for a function class?

jangorecki
  • 16,384
  • 4
  • 79
  • 160
  • Try regular quotes. From the "Writing R Extensions" manual you'll find the following in section 1.5.2 : "(Note that function and class names may be quoted, and reserved words and non-standard names such as [<- and function must be.)" – Chris Nov 22 '15 at 03:31
  • Thanks @Chris, it did work. Please put it as answer so I can accept it. – jangorecki Nov 22 '15 at 15:06

1 Answers1

1

According to Writing R Extensions section 1.5.2, you have to use regular quotes when registering S3 methods that work on objects of class function:

(Note that function and class names may be quoted, and reserved words and non-standard names such as [<- and function must be.)

Chris
  • 1,575
  • 13
  • 20
  • Just to make it clear that direct solution for my example is: `S3method(as.abc, "function")` – jangorecki Nov 22 '15 at 20:37
  • Overloading the reserved words "function" and "list" with an additional meaning will make it hard for anyone who uses the class abc. The OP might instead define two validity-checked classes: an "abc.list" class and an "abc.function" class. These classnames wouldn't have to be quoted in the NAMESPACE file. While I'm nit-picking: the as.abc.list() function would I think be more appropriately named new_abc.list(), since it consists only of a validity check and a class-enrolment. Assigning a new name to an object using "=" is asking for trouble. Using "<-" is easier on everyone. – Clark Thomborson Nov 23 '22 at 10:23