Just wondered about this curious behaviour. I'm trying to learn about classes. Basically setMethod works the first time, but does not seem to work the second time. Faheem. ************************************************************************* setClass("foo", representation(x="numeric")) bar <- function(object) { return(0) } bar.foo <- function(object) { print(object at x) } setMethod("bar", "foo", bar.foo) bar(f) # bar(f) gives 1. bar <- function(object) { return(0) } bar.foo <- function(object) { print(object at x) } setMethod("bar", "foo", bar.foo) f = new("foo", x= 1) bar(f) # bar(f) gives 0, not 1.
On 27/08/2007 5:47 PM, Faheem Mitha wrote:> Just wondered about this curious behaviour. I'm trying to learn about > classes. Basically setMethod works the first time, but does not seem to > work the second time. > Faheem. > ************************************************************************* > setClass("foo", representation(x="numeric")) > > bar <- function(object) > { > return(0) > } > > bar.foo <- function(object) > { > print(object at x) > } > setMethod("bar", "foo", bar.foo)This changes the definition of bar: now it becomes a generic function instead of a simple function.> > bar(f) > > # bar(f) gives 1.(You forgot the f = new("foo", x= 1) line, but that's somewhat obvious.)> > bar <- function(object) > { > return(0) > }Now bar is a regular function again.> > bar.foo <- function(object) > { > print(object at x) > } > setMethod("bar", "foo", bar.foo)Now the generic would call that method, but you've wiped out the generic.> > f = new("foo", x= 1) > > bar(f) > > # bar(f) gives 0, not 1.The problem is that setting a method on a regular function automagically creates a generic for it, but redefining a function doesn't remove the generic. It's still there, somewhere in R's insides, and if you could find it to call it your method would get called. But you're calling the plain old bar() instead. This behaviour makes more sense if you think about generics in other packages. There's a generic called "show" in the methods package. But you can define your own function called "show", and in your workspace, you'd want to call that, not the one from methods. I'd recommend using setGeneric() to create a generic, rather than depending on the automatic creation, to avoid this kind of confusion. Duncan Murdoch
On Mon, 27 Aug 2007, Faheem Mitha wrote:> > Just wondered about this curious behaviour. I'm trying to learn about > classes. Basically setMethod works the first time, but does not seem to > work the second time. > Faheem. > ************************************************************************* > setClass("foo", representation(x="numeric")) > > bar <- function(object) > { > return(0) > } > > bar.foo <- function(object) > { > print(object at x) > } > setMethod("bar", "foo", bar.foo) > > bar(f) > > # bar(f) gives 1.Not for me. It gives> bar(f)Error: object "f" not found Error in bar(f) : error in evaluating the argument 'object' in selecting a method for function 'bar' However, if I do f = new("foo", x= 1) first, it gives 1.> bar <- function(object) > { > return(0) > }Here you have masked the generic bar() with a new function bar(). Redefining bar() is the problem, not the second setMethod().> bar.foo <- function(object) > { > print(object at x) > } > setMethod("bar", "foo", bar.foo)Because there was a generic bar(), even though it is overwritten by the new bar(), setMethod() doesn't automatically create another generic.> f = new("foo", x= 1) > > bar(f) > > # bar(f) gives 0, not 1. >Because bar() isn't a generic function> barfunction(object) { return(0) } If you had used setGeneric() before setMethod(), as recommended, your example would have done what you expected, but it would still have wiped out any previous methods for bar() -- eg, try setMethod("bar","baz", function(object) print("baz")) before you redefine bar(), and notice that getMethod("bar","baz") no longer finds it. -thomas Thomas Lumley Assoc. Professor, Biostatistics tlumley at u.washington.edu University of Washington, Seattle