Re: [Rd] Problem with S3 to S4 transition

From: Martin Morgan <mtmorgan_at_fhcrc.org>
Date: Tue, 16 Mar 2010 17:26:24 -0700

Hi Renard --

On 03/16/2010 05:26 AM, Renard Didier wrote:
> Hello to everybody
>
> I am developing a package using R and have the following problem:
>
> I used to work in a mixture of S3 and S4 mechanism environment: as a
> matter of fact, I used to define my classes (say "DB" for illustration)
> using the setClass function (with representation field), and
> I was using the S3 implicit mechanism writing the functions: print.DB
> and plot.DB.
>
> Recently, I read some interesting papers on the use of S4 mechanism and
> was convinced that I would have some benefit in turning everything on S4
> formalism.
> This is the reason why I simply renamed my previous functions into
> DB.print and DB.plot (by analogy with other functions where the Class
> name is the leading part of the name). My idea was to use the setMethod
> principle to set the DB.print function as the function for the "print"
> method on the "DB" class.
> Therefore, in the .First.Lib file of my package, I introduced the
> setMethod line just after the setClass one, as in the following example:
>
> setClass("DB",
> representation(flag.grid = "logical", ndim = "numeric",
> x0 = "numeric", dx = "numeric", nx = "numeric",
> locators ="character",items = "data.frame"))
> setMethod("show","DB",function(object) DB.print(object))
> setMethod("print",signature(x="DB"),function(x,...) DB.print(x))
> setMethod("plot",signature(x="DB"),function(x,y,...) DB.plot(x))
> setMethod("[" ,signature(x="DB"),db0.getindex)
> setMethod("[<-",signature(x="DB"),db0.setindex)
> setMethod("$" ,signature(x="DB"),db0.get)
> setMethod("$<-",signature(x="DB"),db0.set)

'print' is not needed for S4 objects, 'show' does the job.

Normally one does not place setClass() or setMethod() in .First.lib, but uses them like any other function definition (e.g., in a file methods-DB.R). It can sometimes be important to use a Collates: field in the DESCRIPTION file so that classes are defined before methods that dispatch on them.

>
> As one can notice, I use the same mechanism for SHOW, PLOT and PRINT.
> Finally I created the package and imagined to use it using library
> statement
>
> Surprisingly, when I used the library statement, the program tells me:

>> standardGeneric for "print" defined from package "base"
>> standardGeneric for "plot" defined from package "base"

> and creates two objects in the .GlobalEnv, namely "plot" and "print"
> with the following contents:
>
>> print

> standardGeneric for "print" defined from package "base"
>
> function (x, ...)
> standardGeneric("print")
> <environment: 0xa275c70>
> Methods may be defined for arguments: x
> Use showMethods("print") for currently available ones.
>
> Nothing similar for "show" although my use of setMethod is the same.
>
> I see a main difference as "show" belongs to the "methods" library
> whereas the two other belong to the "base" library. Bu t I could not see
> how to avoid a user of my library to have these message and the two
> objects created.

'show' is already a generic, defined in methods, so a generic does not need to be created. "plot" is a regular R function, so setMethod("plot", ...) has to create a generic and then associate your method with it. When setMethod("plot", ...) is defined as suggested above, the new generic is generated when the package is installed (not loaded, so the message creating a new generic is only presented at installation) and placed in the package environment (e.g., ls(name="package:pkgA")) and not .GlobalEnv. Explicitly calling setGeneric("plot") creates the generic without the information message.

Consider using a NAMESPACE (and .onLoad() rather than .FirstLib).

Best,

Martin

> I am allowed to set the method as I did (I think that I read something
> telling me that I could not do it with methods of the "base" library).
> Otherwiser how can I define the function DB.print as the required method
> for printing objects belonging to the "DB" class.
>
> Thank in advance for you help.
>
>
>
> ______________________________________________
> R-devel_at_r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Martin Morgan
Computational Biology / Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N.
PO Box 19024 Seattle, WA 98109

Location: Arnold Building M1 B861
Phone: (206) 667-2793

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Wed 17 Mar 2010 - 00:29:23 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Wed 17 Mar 2010 - 15:41:04 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive