From ross at biostat.ucsf.edu  Tue Sep 26 21:34:58 2006
From: ross at biostat.ucsf.edu (Ross Boylan)
Date: Tue, 26 Sep 2006 19:34:58 +0000
Subject: [Rd] S4 accessors
In-Reply-To: <m21wpyzfph.fsf@ziti.local>
References: <1159230049.7161.132.camel@iron.psg.net>
	<m2mz8n2prs.fsf@ziti.local> <1159291414.7161.143.camel@iron.psg.net>
	<m21wpyzfph.fsf@ziti.local>
Message-ID: <1159299299.7161.239.camel@iron.psg.net>

On Tue, 2006-09-26 at 10:43 -0700, Seth Falcon wrote:
> Ross Boylan <ross at biostat.ucsf.edu> writes:

> >> If anyone else is going to extend your classes, then you are doing
> >> them a disservice by not making these proper methods.  It means that
> >> you can control what happens when they are called on a subclass. 
> 
> > My style has been to define a function, and then use setMethod if I want
> > to redefine it for an extension.  That way the original version becomes
> > the generic.
> >
> > So I don't see what I'm doing as being a barrier to adding methods.  Am
> > I missing something?
> 
> You are not, but someone else might be: suppose you release your code
> and I would like to extend it.  I am stuck until you decide to make
> generics.
This may be easier to do concretely.
I have an S4 class A.
I have defined a function foo that only operates on that class.
You make a class B that extends A.
You wish to give foo a different implementation for B.

Does anything prevent you from doing 
setMethod("foo", "B", function(x) blah blah)
(which is the same thing I do when I make a subclass)?
This turns my original foo into the catchall method.

Of course, foo is not appropriate for random objects, but that was true
even when it was a regular function.

> 
> > Originally I tried defining the original using setMethod, but this
> > generates a complaint about a missing function; that's one reason I fell
> > into this style.
> 
> You have to create the generic first if it doesn't already exist:
> 
>    setGeneric("foo", function(x) standardGeneric("foo"))
I wonder if it might be worth changing setMethod so that it does this by
default when no existing function exists. Personally, that would fit the
style I'm using better.
> 
> >> For accessors, I like to document them in the methods section of the
> >> class documentation.
> 
> > This is for accessors that really are methods, not my fake
> > function-based accessors, right?
> 
> Which might be a further argument not to have the distinction in the
> first place ;-)
> 
> To me, simple accessors are best documented with the class.  If I have
> an instance, I will read help on it and find out what I can do with
> it.  
> 
> > If you use foo as an accessor method, where do you define the associated
> > function (i.e., \alias{foo})? I believe such a definition is expected by
> > R CMD check and is desirable for users looking for help on foo (?foo)
> > without paying attention to the fact it's a method.
> 
> Yes you need an alias for the _generic_ function.  You can either add
> the alias to the class man page where one of its methods is documented
> or you can have separate man pages for the generics.  This is
> painful.  S4 documentation, in general, is rather difficult and IMO
> this is in part a consequence of the more general (read more powerful)
> generic function based system.
As my message indicates, I too am struggling with an appropriate
documentation style for S4 classes and methods.  Since "Writing R
Extensions" has said "Structure of and special markup for documenting S4
classes and methods are still under development." for as long as I cam
remember, perhaps I'm not the only one.

Some of the problem may reflect the tension between conventional OO and
functional languages, since R remains the latter even under S4.  I'm not
sure if it's the tools or my approach that is making things awkward; it
could be both!

Ross




[Rd] S4 accessors
Ross Boylan