[R] S3 and S4 classes

John Chambers jmc at research.bell-labs.com
Wed Jul 23 21:45:36 CEST 2003

Duncan Murdoch wrote:
> On Wed, 23 Jul 2003 14:53:56 +0200, Laurent Faisnel
> <laurent.faisnel at ariase.com> wrote :
> >Could anyone point me out what's S3-like in
> >the following sample and why it is not fully S4-compatible ?
> ># a function that objects of this class have
> >perform <- function(.Object) UseMethod("perform", .Object);
> It think this is unnecessary, and somewhat S3-like.  A more S4-looking
> way to do the same (?) thing is
> setGeneric("perform", function(.Object) standardGeneric("perform"))
> but I think this will be generated automatically when you define your
> methods.

As Duncan says, this is the S3-style portion of the example.  It's not
wrong, but there are advantages to NOT going this route.

The UseMethod() call says that this is a function with S3-style
methods.  Is that true?  It might well be--you could have a function
perform.default, for example, that was the default method to use.

The disadvantage of hanging on to S3 methods is that they're hidden;
unlike S4 methods, you can't easily find out what methods are defined
(by calling showMethods()).

If you don't  have any existing definition of perform(), you will need
to call setGeneric() as Duncan showed.  The implication is that
perform() doesn't have a default method--unless the argument inherits
from one of the classes in a setMethod() call, the result is an error. 
(If there is a non-generic version of perform, that becomes the default
method, as it would in your example.)

If you DID have a perform.default, you might want to make that
explicitly the S4 default method
  setMethod("perform", "ANY", perform.default)
after the setGeneric call.  Similarly, you could make other S3 methods
into S4 methods.  Then all the methods are visible.

Also, a point of good style, unrelated to methods.  It's not generally a
good idea to have function arguments starting with ".".  Names of this
form are intended for behind-the-scenes manipulations.  By sticking to
names that start with a letter, you avoid the chance of conflicting with
some such manipulation.  So, "Object" rather than ".Object".  (The
reason intialize() uses .Object is exactly BECAUSE it expects
user-defined arguments, in the "...", to start with a letter, and so
chooses .Object to minimize the chance of conflicting.)

 John Chambers
> Duncan Murdoch
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-help

John M. Chambers                  jmc at bell-labs.com
Bell Labs, Lucent Technologies    office: (908)582-2681
700 Mountain Avenue, Room 2C-282  fax:    (908)582-3340
Murray Hill, NJ  07974            web: http://www.cs.bell-labs.com/~jmc

More information about the R-help mailing list