From mtmorgan at fhcrc.org  Thu Dec  3 22:00:28 2009
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Thu, 03 Dec 2009 13:00:28 -0800
Subject: [Rd] group generics
In-Reply-To: <4B144DC4.3020904@biostat.ucsf.edu>
References: <1259109265.8792.22.camel@markov.biostat.ucsf.edu>
	<6ph3a428z2r.fsf@gopher4.fhcrc.org>
	<4B144DC4.3020904@biostat.ucsf.edu>
Message-ID: <4B1826EC.5090504@fhcrc.org>

Hi Ross --

Ross Boylan wrote:
> 
> 
> Martin Morgan wrote:
>> Hi Ross -- 
> 
>> Ross Boylan <ross at biostat.ucsf.edu> writes:
> 
>>> I have classes A and B, where B contains A.  In the implementation of
>>> the group generic for B I would like to use the corresponding group
>>> generic for A.  Is there a way to do that?
> 
>>> setMethod("Arith", signature(e1="numeric", e2="B"), function(e1, e2) {
>>> 	# the next line does not work right
>>>   v <- selectMethod("callGeneric", signature=c("numeric", "A"))(e1, e2)
>>     v <- callGeneric(e1, as(e2, "A"))
> 
>> or probably
> 
>>    v <- callNextMethod(e1, e2)
> 
>> Martin
> 
> A different error this time, one that looks a lot like the report from
> Stephen.Pope at ubs.com on 2007-12-24 concerning callNextMethod:, except
> this is with
> callGeneric.
> 
> HOWEVER, the problem is erratic; when I started from scratch and took
> this code into a workspace and executed the commands, they worked as
> expected.  I had various false starts and revisions, as well as the real
> code on which the example is based, when the error occurred.  I tried
> taking in the real code (which defines generics with Arith from my
> actual classes, and which also fails as below), and the example still
> worked.
> 
> 
> My revised code:
> 
> setClass("A",
>          representation=representation(xa="numeric")
>          )
> 
> setMethod("Arith", signature(e1="numeric", e2="A"), function(e1, e2) {
>   new("A", xa=callGeneric(e1, e2 at xa))
> }
>          )
> 
> setClass("B",
>          representation=representation(xb="numeric"),
>          contains=c("A")
>          )
> 
> setMethod("Arith", signature(e1="numeric", e2="B"), function(e1, e2) {
>   new("B", xb=e1*e2 at xb, callNextMethod())
> }
> )
> 
> Results:
>> options(error=recover)
>> tb <- new("B", xb=1:3, new("A", xa=10))
>> 3*tb
> Error in get(fname, envir = envir) : object '.nextMethod' not found

I feel obliged to respond, since you were following my original
suggestion, but I don't really have a clear answer. I think the error
message is really an issue in the S4 infrastructure, arising from
combining callNextMethod, callGeneric, and group generics; I don't have
further insight on solving the underlying problem, and perhaps I have
misplaced expectations on how these elements are supposed to play
together. A work around is to stick with callGeneric

setClass("A", representation=representation(xa="numeric"))

setMethod("Arith", signature(e1="numeric", e2="A"), function(e1, e2) {
    new("A", xa=callGeneric(e1, e2 at xa))
})

setClass("B",
         representation=representation(xb="numeric"),
         contains=c("A"))

setMethod("Arith", signature(e1="numeric", e2="B"), function(e1, e2) {
    new("B", xb=e1*e2 at xb, callGeneric(e1, as(e2, "A")))
})

tb <- new("B", xb=1:3, new("A", xa=10)); 3 * tb

Martin

> 
> Enter a frame number, or 0 to exit
> 
>  1: 3 * tb
>  2: 3 * tb
>  3: test.R#16: new("B", xb = e1 * e2 at xb, callNextMethod())
>  4: initialize(value, ...)
>  5: initialize(value, ...)
>  6: callNextMethod()
>  7: .nextMethod(e1 = e1, e2 = e2)
>  8: test.R#6: new("A", xa = callGeneric(e1, e2 at xa))
>  9: initialize(value, ...)
> 10: initialize(value, ...)
> 11: callGeneric(e1, e2 at xa)
> 12: get(fname, envir = envir)
> 
> Selection: 0
> 
> The callGeneric in frame 11 is trying to get the primitive for
> multiplying numeric times numeric.  Quoting from Pope's analysis:
> [The primitive...]
>> does not get the various "magic" variables such as .Generic, .Method,
>> etc. defined in its frame. Thus, callGeneric() fails when, failing to
>> find ".Generic" then takes the function symbol for the call (which
>> callNextMethod() has constructed to be ".nextMethod") and attempts to
>> look it up, which of course also fails, leading to the resulting error
>> seen above.
> 
> I'm baffled, and hoping someone on the list has an idea.
> I'm running R 2.10 under ESS (in particular, I use c-c c-l in the code
> file to read in the code) on XP.

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



[Rd] group generics
Martin Morgan