Hello, ?as.character says that the as.character function is a generic with usage: as.character(x, ...). So, I want to create an S4 object with an as.character method following the above usage, but I get the below error telling me that ... isn't in the generic for as.character.> setClass("tmp", "numeric") > setMethod("as.character", "tmp", function(x, ...) paste(x, c(...)))Error in rematchDefinition(definition, fdef, mnames, fnames, signature) : Methods can add arguments to the generic only if "..." is an argument to the generic Am I reading the documentation incorrectly? How do I correctly pass the ... object to the method for this "tmp" object? However I note that looking at the generic function, I see no mention of ... (despite the documentation).> getGeneric("as.character")standardGeneric for "as.character" defined from package "base" function (x) standardGeneric("as.character", .Primitive("as.character")) <environment: 0145EDC4> Methods may be defined for arguments: x So, briefly, is the documentation wrong? Am I doing something wrong? Can I create an as.character method and pass additional arguments to it as I think I should be able to? Thanks, Robert Robert McGehee Geode Capital Management, LLC 53 State Street, 5th Floor | Boston, MA | 02109 Tel: 617/392-8396 Fax:617/476-6389 mailto:robert.mcgehee at geodecapital.com This e-mail, and any attachments hereto, are intended for use by the addressee(s) only and may contain information that is (i) confidential information of Geode Capital Management, LLC and/or its affiliates, and/or (ii) proprietary information of Geode Capital Management, LLC and/or its affiliates. If you are not the intended recipient of this e-mail, or if you have otherwise received this e-mail in error, please immediately notify me by telephone (you may call collect), or by e-mail, and please permanently delete the original, any print outs and any copies of the foregoing. Any dissemination, distribution or copying of this e-mail is strictly prohibited.
You seem to be confusing `generic' with `S4 generic', and `method' with `S4 method'. Note that all references to `generic' and `method' outside the `methods' package are not to S4 concepts unless explicitly stated. On Thu, 13 Jan 2005, McGehee, Robert wrote:> Hello, > ?as.character says that the as.character function is a generic with > usage: as.character(x, ...). So, I want to create an S4 object with an > as.character method following the above usage, but I get the below error > telling me that ... isn't in the generic for as.character. > >> setClass("tmp", "numeric") >> setMethod("as.character", "tmp", function(x, ...) paste(x, c(...))) > Error in rematchDefinition(definition, fdef, mnames, fnames, signature) > : > Methods can add arguments to the generic only if "..." is an > argument to the generic > > Am I reading the documentation incorrectly? How do I correctly pass the > ... object to the method for this "tmp" object? > > However I note that looking at the generic function, I see no mention of > ... (despite the documentation). >> getGeneric("as.character") > standardGeneric for "as.character" defined from package "base" > > function (x) > standardGeneric("as.character", .Primitive("as.character")) > <environment: 0145EDC4> > Methods may be defined for arguments: x > > > So, briefly, is the documentation wrong? Am I doing something wrong? Can > I create an as.character method and pass additional arguments to it as I > think I should be able to?Briefly, No, yes, yes. -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Professor Ripley, You are quite correct, I did have some S3/S4 confusion. Thank you. By using an S3 method with the documented usage, I had no trouble writing an appropriate as.character method. I had also not absorbed the fact that S3 and S4 generics might (and do!) have different argument lists, as I see that the S3 as.character generic takes (x, ...), and the S4 generic takes just (x). I'd also like to ask a follow-up question to clarify this difference. The documentation for ?.BasicFunsList (first page of methods package documentation) reads: "Functions in R that are defined as '.Primitive(<name>)' are not suitable for formal methods, because they lack the basic reflectance property." As "as.character"() calls .Primitive("as.character"), I read the above sentence to say that S4 methods are not appropriate for this function. But certainly S4 methods _can_ be defined for .Primitives, and I can seemingly get the argument list for such a primitive with the getGeneric() function. Is the point then that S4 cannot pass on extended (...) argument list for some primitives (such as the message below), and thus informal S3 methods are required in some cases? Or perhaps I'm missing the point entirely. Any clarification is greatly appreciated. Thanks, Robert -----Original Message----- From: Prof Brian Ripley [mailto:ripley at stats.ox.ac.uk] Sent: Thursday, January 13, 2005 5:58 PM To: McGehee, Robert Cc: r-help at stat.math.ethz.ch Subject: Re: [R] as.character methods You seem to be confusing `generic' with `S4 generic', and `method' with `S4 method'. Note that all references to `generic' and `method' outside the `methods' package are not to S4 concepts unless explicitly stated. On Thu, 13 Jan 2005, McGehee, Robert wrote:> Hello, > ?as.character says that the as.character function is a generic with > usage: as.character(x, ...). So, I want to create an S4 object with an > as.character method following the above usage, but I get the belowerror> telling me that ... isn't in the generic for as.character. > >> setClass("tmp", "numeric") >> setMethod("as.character", "tmp", function(x, ...) paste(x, c(...))) > Error in rematchDefinition(definition, fdef, mnames, fnames,signature)> : > Methods can add arguments to the generic only if "..." is an > argument to the generic > > Am I reading the documentation incorrectly? How do I correctly passthe> ... object to the method for this "tmp" object? > > However I note that looking at the generic function, I see no mentionof> ... (despite the documentation). >> getGeneric("as.character") > standardGeneric for "as.character" defined from package "base" > > function (x) > standardGeneric("as.character", .Primitive("as.character")) > <environment: 0145EDC4> > Methods may be defined for arguments: x > > > So, briefly, is the documentation wrong? Am I doing something wrong?Can> I create an as.character method and pass additional arguments to it asI> think I should be able to?Briefly, No, yes, yes. -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Please use R-devel not R-help for esoteric programming questions: I have moved this there. [See the posting guide.] Anything involving the methods package is definitely not for R-help: I doubt if 1% of the readership of R-help have knowingly used it. On Thu, 13 Jan 2005, McGehee, Robert wrote:> Professor Ripley, > You are quite correct, I did have some S3/S4 confusion. Thank you. By > using an S3 method with the documented usage, I had no trouble writing > an appropriate as.character method. > > I had also not absorbed the fact that S3 and S4 generics might (and do!) > have different argument lists, as I see that the S3 as.character generic > takes (x, ...), and the S4 generic takes just (x). > > I'd also like to ask a follow-up question to clarify this difference. > The documentation for ?.BasicFunsList (first page of methods package > documentation) reads: > > "Functions in R that are defined as '.Primitive(<name>)' are not > suitable for formal methods, because they lack the basic reflectance > property."Please read on: You can't find the argument list for these functions by examining the function object itself. ... In the absence of reflectance, this list provides the relevant information via a dummy function associated with each of the known specials for which methods are allowed. ... A generic function created via 'setMethod', for example, for one of these special functions will have the argument list from '.BasicFunsList'. If no entry exists, the argument list '(x, ...)' is assumed.> As "as.character"() calls .Primitive("as.character"), I read the above > sentence to say that S4 methods are not appropriate for this function. > But certainly S4 methods _can_ be defined for .Primitives, and I can > seemingly get the argument list for such a primitive with the > getGeneric() function. Is the point then that S4 cannot pass on extended > (...) argument list for some primitives (such as the message below), andNo, as look at the list, some of which have ... in their argument list.> thus informal S3 methods are required in some cases? Or perhaps I'm > missing the point entirely. Any clarification is greatly appreciated.I am afraid I don't understand why someone who does not appreciate the differences here is using S4 methods. I see you have sent a bug report on applying formals<- to new("function") which shows you do not understand the difference between that and a function. Please look at the code for the function getGeneric: that's the detailed documentation. It contains if (is.primitive(baseDef)) { value <- genericForPrimitive(f) and it seems John Chambers has defined an S4 generic for as.character with one arg, "x". Had he not done so it would have been (x, ...). My guess is that this is because in S the arg list is (x) and he overlooked that it was not in R, but only he knows.> Thanks, > Robert > > -----Original Message----- > From: Prof Brian Ripley [mailto:ripley@stats.ox.ac.uk] > Sent: Thursday, January 13, 2005 5:58 PM > To: McGehee, Robert > Cc: r-help@stat.math.ethz.ch > Subject: Re: [R] as.character methods > > > You seem to be confusing `generic' with `S4 generic', and `method' with > `S4 method'. > > Note that all references to `generic' and `method' outside the `methods' > > package are not to S4 concepts unless explicitly stated. > > On Thu, 13 Jan 2005, McGehee, Robert wrote: > >> Hello, >> ?as.character says that the as.character function is a generic with >> usage: as.character(x, ...). So, I want to create an S4 object with an >> as.character method following the above usage, but I get the below > error >> telling me that ... isn't in the generic for as.character. >> >>> setClass("tmp", "numeric") >>> setMethod("as.character", "tmp", function(x, ...) paste(x, c(...))) >> Error in rematchDefinition(definition, fdef, mnames, fnames, > signature) >> : >> Methods can add arguments to the generic only if "..." is an >> argument to the generic >> >> Am I reading the documentation incorrectly? How do I correctly pass > the >> ... object to the method for this "tmp" object? >> >> However I note that looking at the generic function, I see no mention > of >> ... (despite the documentation). >>> getGeneric("as.character") >> standardGeneric for "as.character" defined from package "base" >> >> function (x) >> standardGeneric("as.character", .Primitive("as.character")) >> <environment: 0145EDC4> >> Methods may be defined for arguments: x >> >> >> So, briefly, is the documentation wrong? Am I doing something wrong? > Can >> I create an as.character method and pass additional arguments to it as > I >> think I should be able to? > > Briefly, No, yes, yes. > > -- > Brian D. Ripley, ripley@stats.ox.ac.uk > Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ > University of Oxford, Tel: +44 1865 272861 (self) > 1 South Parks Road, +44 1865 272866 (PA) > Oxford OX1 3TG, UK Fax: +44 1865 272595 > >-- Brian D. Ripley, ripley@stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595