From jmc at r-project.org  Mon Jun  9 20:35:46 2008
From: jmc at r-project.org (John Chambers)
Date: Mon, 09 Jun 2008 14:35:46 -0400
Subject: [Rd] R CMD CHECK WARNING inappropriate for S4 method?
In-Reply-To: <6phd4mr7fd7.fsf@lamprey.fhcrc.org>
References: <6phd4mr7fd7.fsf@lamprey.fhcrc.org>
Message-ID: <484D7802.3060804@r-project.org>

This one is subtle, and has mostly to do with namespace and imports, 
only secondarily to do with methods.  Bear with a fairly long story.

The description below is for a simple package P1 that imitates the 
pattern of imports in GSEABase.

First, what's generating the warning?  The function undoc() in the tools 
package looks for all the methods defined in the current package, for 
"union" in this case.  In r-devel, that uses the function findMethods().

What it gets is:
 > names(findMethods("union", where = 2))
[1] "ANY#ANY"             "graph#graph"         "testClass#testClass"

(where "testClass" is the new class that P1 is adding.)

What it "normally" gets in these circumstances is:
 > names(findMethods("union", where = 2))
[1] "testClass#testClass"

In the first case, undoc() naturally assumes you created all the methods 
and wants you to document them.

The question, then, is why are you getting the extra methods?

The answer, to the extent I understand it, is that P1 (and GSEABase) 
used the
  Imports:graph
directive in the DESCRIPTION file, instead of explicitly doing the 
import() commands in the NAMESPACE file.  Just what this does 
differently  I'm not sure, but the effect is that the generic version of 
union() in the "graph" package is no longer in the imports environment 
for package P1:

 > n1 = asNamespace("P1")
 > objects(parent.env(n1), all=TRUE, pattern="union")
character(0)

The result is that P1 owns the union() generic and all its methods.  In 
particular, a generic function "union" is created in P1.

The alternative way to specify the imports is to use the NAMESPACE file, 
say with:

import(graph)

Package "graph" must be added to the Depends: line of the DESCRIPTION 
file, instead of being in the Imports: line.  (Otherwise, you still get 
the new generic, owning all the methods.)

Now the generic version of union() is in the imports environment for P1; 
the setMethod() call in P1 does not create a new generic.  We can see 
this by:
 > n1 = asNamespace("P1")
 > objects(parent.env(n1), all=TRUE, pattern="union")
[1] ".__M__union:base" ".__T__union:base" "union"          


One final catch: In this version, you do need to ensure that the user's 
call to union() sees the generic version at run time, and not the 
nongeneric version in base.  Either require(graph) or, in P1's NAMESPACE:

export(union)

Perhaps needless to say, this is all a bit more subtle than one would like.

John





Martin Morgan wrote:
> The package 'graph' defines classes graph and graphNEL (extending
> graph) and a union,graph,graph-method. These are all exported and
> fully documented.
>
> The package 'GSEABase' Imports: graph and importClassesFrom(graph,
> graphNEL). GSEABase defines methods on union for its own classes (not
> graph / graphNEL), and has exportMethods(union).
> union,graph,graph-method is not used in GSEABase.
>
> R version 2.8.0 Under development (unstable) (2008-06-08 r45879)
> reports from R CMD CHECK GSEABase
>
> * checking for missing documentation entries ... WARNING
> Undocumented S4 methods:
>   generic 'union' and siglist 'graph,graph'
>
> I guess union,graph,graph-method is exposed to the user indirectly by
> its import along with the graph class and export along with the
> newly-defined union methods.
>
> It would seem inappropriate to document union,graph,graph-method in
> GSEABase. Making GSEABase Depend: graph rather than Import: graph does
> not help.
>
> Any guidance welcome.
>
> Thanks,
>
> Martin
>



[Rd] R CMD CHECK WARNING inappropriate for S4 method?
John Chambers