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