Greg Minshall
2013-Feb-14 16:57 UTC
[R] 2 setGeneric's, same name, different method signatures
hi. below is a small test case (hopefully minimal, though i'm still a bit confused about initializers). i would have guessed (and maybe i still would have been right) that one could re-use the name of a generic function for functions with different numbers of arguments. in the case below, class A's bB() queries the status of a single A object, so bB(A) (where here "A" is an instance of class A, just for "clarity") returns a value. class B's bB() compares values in two B objects, and returns the minimum, so bB(B1, B2) are its methods. after loading the file, i see the method for A's bB has disappeared (as measured by showMethods("bB"), as well as trying bB(A). if i have R re-parse the setGeneric/setMethod A's bB(), then B's bB() disappears. somehow my code, or my model of how things work, is wrong. any ideas what am i missing? cheers, Greg Minshall ---- setClass("A", representation( x="numeric")); setMethod( f="initialize", signature="A", definition=function(.Object) { .Object at x <- 23; return(.Object) }); setGeneric("bB", function(me) standardGeneric("bB")); setMethod( "bB", signature("A"), definition=function(me) { return (new("B", me at x))}); setClass("B", representation( bx="numeric")); setMethod( "initialize", signature("B"), definition=function(.Object, x) { .Object at bx <- x; return(.Object); }); setGeneric("bB", function(b1, b2) standardGeneric("bB")); setMethod( "bB", signature("B", "B"), definition=function(b1, b2) { return(new("B", min(b1 at bx, b2 at bx)))});
Greg Minshall
2013-Feb-14 21:12 UTC
[R] 2 setGeneric's, same name, different method signatures
i'm answering my own question: 1. setGeneric's override (wipe out, really) previous ones. (this is pointed out in section 5.3 of "A (Not So) Short Introduction to S4 Object Oriented Programming in R" by Christophe Genolini.) 2. the *names* of the formals are important. 3. one can specify a method that takes a subset of the formals declared in the setGeneric. so, in my example, changing "me" to "b1" in A's bB(), allows A to use B's setGeneric(). for completeness, below is my code that works (or, seems to!). if anyone knows, in #3 above, how A can specify that "no b2 is allowed!", i'd be curious. cheers, Greg Minshall ---- setClass("A", representation( x="numeric")); setMethod( f="initialize", signature="A", definition=function(.Object) { .Object at x <- 23; return(.Object) }); setGeneric("bB", function(me) standardGeneric("bB")); setMethod( "bB", signature("A"), definition=function(b1) { return (new("B", b1 at x))}); setClass("B", representation( bx="numeric")); setMethod( "initialize", signature("B"), definition=function(.Object, x) { .Object at bx <- x; return(.Object); }); setGeneric("bB", function(b1, b2) standardGeneric("bB")); setMethod( "bB", signature("B", "B"), definition=function(b1, b2) { return(new("B", min(b1 at bx, b2 at bx)))});
Martin Morgan
2013-Feb-15 02:43 UTC
[R] 2 setGeneric's, same name, different method signatures
On 2/14/2013 8:57 AM, Greg Minshall wrote:> hi. below is a small test case (hopefully minimal, though i'm still a > bit confused about initializers). > > i would have guessed (and maybe i still would have been right) that one > could re-use the name of a generic function for functions with different > numbers of arguments. in the case below, class A's bB() queries the > status of a single A object, so bB(A) (where here "A" is an instance of > class A, just for "clarity") returns a value. class B's bB() compares > values in two B objects, and returns the minimum, so bB(B1, B2) are its > methods. > > after loading the file, i see the method for A's bB has disappeared (as > measured by showMethods("bB"), as well as trying bB(A). if i have R > re-parse the setGeneric/setMethod A's bB(), then B's bB() disappears. > > somehow my code, or my model of how things work, is wrong. any ideas > what am i missing? > > cheers, Greg Minshall > ---- > setClass("A", > representation( > x="numeric")); > > setMethod( > f="initialize", > signature="A", > definition=function(.Object) { > .Object at x <- 23; > return(.Object) > }); > > setGeneric("bB", function(me) standardGeneric("bB")); > setMethod( > "bB", > signature("A"), > definition=function(me) { > return (new("B", me at x))}); > > setClass("B", representation( > bx="numeric")); > > setMethod( > "initialize", > signature("B"), > definition=function(.Object, x) { > .Object at bx <- x; > return(.Object); > }); > > setGeneric("bB", function(b1, b2) standardGeneric("bB"));Hi Greg -- this setGeneric is over-writing the first, as would f = function() "first" f = function() "second" f() # "second" If you'd like to dispatch on a single argument, then setGeneric("one", function(x, ...) standardGeneric("one")) setMethod("one", "A", function(x, ...) "A-method") setMetohd("one", "B", function(x, y, ...) "B-method") The '...' in the generic allow you to add arguments that are 'picked off' by methods. The user could provide any value for y, not only an object of class "B". If you'd like to dispatch sometimes on two arguments then setGeneric("two", function(x, y, ...) standardGeneric("two")) setMethod("two", c("A", "ANY"), function(x, y, ...) "A,ANY-method") setMethod("two", c("B", "B"), function(x, y, ...) "B,B-method") then two(new("A")), two(new("A"), new("A")) and two(new("A"), new("B")) end up in A,ANY,two-method while two(new("B"), new("B")) ends up in "B,B,two-method". Other combinations are errors. One might instead not define A,ANY but instead setMethod("two", c("A", "missing"), function(x, y, ...) "A,missing-method") and then two(new("A"), new("A")) would be an error. Multiple dispatch is complicated, and perhaps best to avoid if possible. It's possible to write a generic and methods that dispatch on '...', with the requirement that all classes are the same; this in the spirit of comparing two B's and returning the smaller; see ?dotsMethods though again this is not a trivial use case. Hope that helps enough. Martin> setMethod( > "bB", > signature("B", "B"), > definition=function(b1, b2) { > return(new("B", min(b1 at bx, b2 at bx)))}); > > ______________________________________________ > R-help at r-project.org 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. >-- Dr. Martin Morgan, PhD Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109
Greg Minshall
2013-Feb-15 21:36 UTC
[R] 2 setGeneric's, same name, different method signatures
William,> and here mention "intra-class name clashes" (I'm not sure what you > mean by this).sorry, i meant, in something like C++, if i have a class Foo and you have a class Bar, then i can invent whatever method names/signatures i want, independent of whatever method names/signatures *you* want. *i* just need to make sure i don't introduce incompatible methods with the same name/signature *within* Foo. cheers, Greg
William Dunlap
2013-Feb-15 21:42 UTC
[R] 2 setGeneric's, same name, different method signatures
I thought you were thinking of the R class system (the S3 and S4 ones anyway) as if it were C++'s. It is quite different. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: Greg Minshall [mailto:minshall at umich.edu] > Sent: Friday, February 15, 2013 1:37 PM > To: William Dunlap > Cc: r-help at r-project.org > Subject: Re: 2 setGeneric's, same name, different method signatures > > William, > > > and here mention "intra-class name clashes" (I'm not sure what you > > mean by this). > > sorry, i meant, in something like C++, if i have a class Foo and you > have a class Bar, then i can invent whatever method names/signatures i > want, independent of whatever method names/signatures *you* want. *i* > just need to make sure i don't introduce incompatible methods with the > same name/signature *within* Foo. > > > cheers, Greg