Skip to content

Problem in 'methods' package (PR#4525)

2 messages · David James, John Chambers

#
Hello,

It seems to me that Fernando may be right.  The problem seems to be
in R 1.8.0 when defining generics with explicit valueClass.  E.g., 

R-1.7.1:

   > setGeneric("foo", function(x) standardGeneric("foo"), valueClass="numeric")
   > setMethod("foo", "numeric", function(x) x )
   > foo(pi)
   [1] 3.141593

R-devel (1.9.0):  (I don't have 1.8.0 handy at this moment).

   > setGeneric("foo", function(x) standardGeneric("foo"), valueClass="numeric")
   > setMethod("foo", "numeric", function(x) x )
   > foo(pi)
   Error in foo(pi) : couldn't find function ".valueClassTest"

whether the problem is in the methods package or the namespace code,
I cannot say.

--
David
Uwe Ligges wrote:

  
    
#
David James wrote:
The simple patch is to add

export(.valueClassTest)

to the NAMESPACE file in the methods package.  This has been done &
committed to r-patched.

However, the longterm best approach is not so obvious.  The valueClass
argument to setGeneric is an addition to the API in the green book.  If
we want to keep it, a different implementation will be needed.

The current mechanism revises the body of the generic function to
include the call to .valueClassTest, but leaves the class of the generic
as "standardGeneric", which is in principle wrong.  A standardGeneric
function is defined to ONLY dispatch methods.  In the present version of
R, that doesn't matter because the body of the function is evaluated as
for any function, but in the future we want to take advantage of
"standardGeneric"-ness by special evaluation.

At that point, the valueClass= argument would need to create a
nonstandardGenericFunction object.  OK, but that raises the question of
whether this special mechanism is worth having.  The class validity test
is just a special case of the general idea of nonstandard generic
functions.  In the example, the call to setGeneric could be of the form
setGeneric("foo", def = fooDef), where fooDef is something like

function(x) {
  value <- standardGeneric("foo")
  if(!is(value,"numeric"))
    stop("foo must return a numeric object for any argument")
  value
}
This is a special case of generics that impose some validity requirement
on the value returned by the method.

Should we complicate the definition of generic functions just to deal
with the particular case of checking for a list of classes?  Seems
questionable, given that it's not imposed by the API.

John