Re: [Rd] super basic questions about S4 classes

From: Andreas Borg <andreas.borg_at_unimedizin-mainz.de>
Date: Fri, 08 Apr 2011 09:06:03 +0200

Hi Andre,

  1. Keep in mind that a S4 method belongs to a specific generic function, not to a specific object or class. There is none such thing as a "class member function" in the S4 system. As an example for illustration, consider the following class definitions in Java:

class myClassA
{

    int a;
    int myMethod();
}

class myClassB
{

    double b;
     int myMethod()
}

Assuming that myClassA and myClassB are not related by inheritance, the two instances of "myMethod" have nothing to do with each other. With S4 classes, you would have something like:

setClass("myClassA", representation(a="integer")) setClass("myClassB", representation(b="numeric"))

setGeneric("myMethod", function(x) standardGeneric("myMethod")) setMethod("myMethod", "myClassA", function(x) {"myMethodA"}) setMethod("myMethod", "myClassB", function(x) {"myMethodB"})

where the instances of myMethod belong to the same generic function. Note that because the methods do not belong to a specific class / object, the object on which to call must be passed as argument. Futhermore, it is impossible to have a method with a different argument list than the generic. Based on the code above, the following gives an error:

setClass("myClassC", representation(c="character")) setMethod("myMethod", "myClassC", function(x,y) {"myMethodC"})

while in Java it is no problem to have

class myClassC
{

    char c[];
    int myMethod(int x, int y)
}

with a different argument list for myMethod.

(Of course, different argument lists in methods are possible if one uses "..." in the generic, this example was just meant as an illustration of the conceptual difference between class methods and generic functions.)

There is a new approach in R called "reference classes", which might provide what you are looking for. But I am not familiar with this paradigm. See ?ReferenceClasses.

2. A function in R is stored in a variable of the same name - as there can be only one variable with a distinct name (within the same scope), no overloading is possible. What I usually do is to provide all possible arguments and check which ones are missing (via missing()) to determine which to use to construct the object. Another possibility would be to make the constructor a method which dispatches on the parameter types.

3. S4 methods can be debugged with trace(), to which a method name and a signature can be passed. I think there is an item in the FAQ about this. There is one peculiarity with debugging if you have a method that has additional arguments compared to the generic, for example:

setGeneric("myMethod", function(x, ...) standardGeneric("myMethod")) setMethod("myMethod", "myClassA", function(x,y) {"myMethodA"})

In this case, the implementation for myMethod will define and call an inner function ".local". In order to trace into this function, you have to call debug(.local) from the browser once the method has been traced.

Hope this helps,

Andreas

A Zege schrieb:
> Apologies for asking something that is probably super obvious, i just started
> with S4 classes and i guess i am not finding documentation that layout the
> grammar rules and give enough examples. Some questions i am having are these
>
> 1. I understand that main method of writing a member function is to write a
> generic function and setMethod for this particular object. This, however,
> presumes that there is "virtuality" for this function, i.e. it could be used
> with other inherited classes . Truth is, many, if not most of my functions
> don't have virtuality in mind. I want to write them inside classes to
> achieve incapsulaton only -- use class member data without passing it as
> parameters or making global to a bunch of functions and have some specific
> class member functions that don't pollute a global namespace and can be
> called only for a particular class. This is what i know how to do with
> enclosures in R. Is there some obvious way of setting this environment local
> to a class without writing generic functions that i am missing?
>
> 2. Is it possible to overload functions in other ways than having default
> parameter values and prototypes?
> For example, can i have two constructors with completely different sets of
> parameters?
>
> 3. Is there some good way to debug S4 classes? I am very fond of mtrace()
> from debug package, but the simple set of commands i normally use doesn't
> take me into class methods.
>
>
> Would appreciate any pointers on these..
>
>
> --
> View this message in context: http://r.789695.n4.nabble.com/super-basic-questions-about-S4-classes-tp3428591p3428591.html
> Sent from the R devel mailing list archive at Nabble.com.
>
> ______________________________________________
> R-devel_at_r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

-- 
Andreas Borg
Medizinische Informatik

UNIVERSITÄTSMEDIZIN
der Johannes Gutenberg-Universität
Institut für Medizinische Biometrie, Epidemiologie und Informatik
Obere Zahlbacher Straße 69, 55131 Mainz
www.imbei.uni-mainz.de

Telefon +49 (0) 6131 175062
E-Mail: borg_at_imbei.uni-mainz.de

Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte 
Informationen. Wenn Sie nicht der
richtige Adressat sind oder diese E-Mail irrtümlich erhalten haben, 
informieren Sie bitte sofort den
Absender und löschen Sie diese Mail. Das unerlaubte Kopieren sowie die 
unbefugte Weitergabe
dieser Mail und der darin enthaltenen Informationen ist nicht gestattet.

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Fri 08 Apr 2011 - 07:14:25 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 Fri 08 Apr 2011 - 15:10:44 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