On 08/09/2013 07:45 AM, Bert Gunter wrote:
Simon:

Have a look at the "proto" package for which there is a vignette. You
may find it suitable for your needs and less intimidating.

Won't help much with S4, though! Some answers here

http://stackoverflow.com/questions/5437238/which-packages-make-good-use-of-s4-objects

including from Bioconductor simple class in EBImage, the advanced IRanges package and the 'toy' StudentGWAS.

Martin


Cheers,
Bert

On Fri, Aug 9, 2013 at 7:40 AM, Simon Zehnder <[email protected]> wrote:
Hi Martin,

thank you very much for this profound answer! Your added design advice is very 
helpful, too!

For the 'simple example': Sometimes I am still a little overwhelmed from a 
certain setting in the code and my ideas how I want to handle a process. But I 
learn from session to session. In future I will also span the lines more than 
80 columns. I am used to the indent in my vim editor.

I have one further issue: I do know, that you are one of the leading developers 
of the bioconductor package which uses (as far as I have read) extensively OOP 
in R. Is there a package you could suggest to me to learn from by reading and 
understanding the code? Where can I find the source code?

Best

Simon


On Aug 8, 2013, at 10:00 PM, Martin Morgan <[email protected]> wrote:

On 08/04/2013 02:13 AM, Simon Zehnder wrote:
So, I found a solution: First in the "initialize" method of class C coerce
the C object into a B object. Then call the next method in the list with the
B class object. Now, in the "initialize" method of class B the object is a B
object and the respective "generateSpec" method is called. Then, in the
"initialize" method of C the returned object from "callNextMethod" has to be
written to the C class object in .Object. See the code below.

setMethod("initialize", "C", function(.Object, value) {.Object@c <- value;
object <- as(.Object, "B"); object <- callNextMethod(object, value);
as(.Object, "B") <- object; .Object <- generateSpec(.Object);
return(.Object)})

This setting works. I do not know though, if this setting is the "usual" way
such things are done in R OOP. Maybe the whole class design is
disadvantageous. If anyone detects a mistaken design, I am very thankful to
learn.

Hi Simon -- your 'simple' example is pretty complicated, and I didn't really 
follow it in detail! The code is not formatted for easy reading (e.g., lines 
spanning no more than 80 columns) and some of it (e.g., generateSpec) might not 
be necessary to describe the problem you're having.

A good strategy is to ensure that 'new' called with no arguments works (there 
are other solutions, but following this rule has helped me to keep my classes 
and methods simple). This is not the case for

  new("A")
  new("C")

The reason for this strategy has to do with the way inheritance is implemented, 
in particular the coercion from derived to super class. Usually it is better to 
provide default values for arguments to initialize, and to specify arguments 
after a '...'. This means that your initialize methods will respects the 
contract set out in ?initialize, in particular the handling of unnamed 
arguments:

     ...: data to include in the new object.  Named arguments
          correspond to slots in the class definition. Unnamed
          arguments must be objects from classes that this class
          extends.

I might have written initialize,A-method as

  setMethod("initialize", "A", function(.Object, ..., value=numeric()){
      .Object <- callNextMethod(.Object, ..., a=value)
      generateSpec(.Object)
  })

Likely in a subsequent iteration I would have ended up with (using the 
convention that function names preceded by '.' are not exported)

  .A <- setClass("A", representation(a = "numeric", specA = "numeric"))

  .generateSpecA <- function(a) {
      1 / a
   }

  A <- function(a=numeric(), ...) {
      specA <- .generateSpecA(a)
      .A(..., a=a, specA=specA)
  }

  setMethod(generateSpec, "A", function(object) {
      .generateSpecA(object@a)
  })

ensuring that A() returns a valid object and avoiding the definition of an 
initialize method entirely.

Martin


Best

Simon


On Aug 3, 2013, at 9:43 PM, Simon Zehnder <[email protected]>
wrote:

setMethod("initialize", "C", function(.Object, value) {.Object@c <- value;
.Object <- callNextMethod(.Object, value); .Object <-
generateSpec(.Object); return(.Object)})

______________________________________________ [email protected] mailing
list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting
guide http://www.R-project.org/posting-guide.html and provide commented,
minimal, self-contained, reproducible code.



--
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

______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.





--
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

______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to