From maechler at stat.math.ethz.ch  Sat Dec  2 17:11:22 2006
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Sat, 2 Dec 2006 17:11:22 +0100
Subject: [Rd] promptClass misses methods
In-Reply-To: <20061201193320.GY4431@wheat.betterworld.us>
References: <20061201062906.GB8201@wheat.betterworld.us>
	<17776.1530.328130.767021@stat.math.ethz.ch>
	<20061201193320.GY4431@wheat.betterworld.us>
Message-ID: <17777.42410.517603.635881@stat.math.ethz.ch>

>>>>> "RossB" == Ross Boylan <ross at biostat.ucsf.edu>
>>>>>     on Fri, 1 Dec 2006 11:33:21 -0800 writes:

    RossB> On Fri, Dec 01, 2006 at 11:37:46AM +0100, Martin
    RossB> Maechler wrote:
    >> >>>>> "RossB" == Ross Boylan <ross at biostat.ucsf.edu>
    >> >>>>> on Thu, 30 Nov 2006 22:29:06 -0800 writes:
    >> 
    RossB> I've had repeated problems with promptClass missing
    RossB> methods, usually telling me a class has no methods
    RossB> when it does.
    >>
    RossB> In my current case, I've defined an S4 class
    RossB> "mspathCoefficients" with a print method
    RossB> setMethod("print", signature(x="mspathCoefficients"),
    RossB> function(x, ...)  { # etc
    >>  You should *not* define "print" methods for S4 classes;
    >> rather you should define "show" methods.

    RossB> Is that because print is used by the S3 system?  

no, not really.
    RossB> And is the general rule to avoid using S3 methods for S4
    RossB> classes?

Well your wording is murky, but no, you *should* define (S4) methods 
for S3 generics very well.  The S3 generics are automagically
promoted to S4 generics as soon as you define an S4 method for it.

print() is just a big exception.

    RossB>   For example, http://www.omegahat.org/RSMethods/Intro.pdf, which is
    RossB> referenced in the package help for methods, discusses
    RossB> show, print and plot as 3 alternatives in S4 (p. 9,
    RossB> though a footnote says that at that time--2001--R
    RossB> didn't recognize formal methods for printing
    RossB> objects.)

2001 is way in the past concerning S4 implementation in R.
Specifically, using S4 in R; we'd   **very strongly** recommend
R 2.4.0 (and ideally even R-patched) because of several recent
good developments.

    RossB> I've been unable to locate much information about
    RossB> combining S3 and S4 methods, though I recall seeing a
    RossB> note saying this issue was still to be addressed in
    RossB> R.  Perhaps it has been now, with setOldClass?  At
    RossB> any rate, the help for that method addresses classes
    RossB> rather than methods, and I didn't see anything in
    RossB> ?Methods, ?setMethod, or ?setGeneric.

    RossB> show() raises two additional issues for me.  First,
    RossB> it takes a single argument, and I want to be able to
    RossB> pass in additional arguments via ... .  

That's not possible currently.

And I agree that in certain cases, I would want to have the
flexibility of print(..) there;
One case is for printing/showing fitted LMER objects; the
following code is used :

  ## This is modeled a bit after  print.summary.lm :
  printMer <- function(x, digits = max(3, getOption("digits") - 3),
		       correlation = TRUE, symbolic.cor = x$symbolic.cor,
		       signif.stars = getOption("show.signif.stars"), ...)
  {
	  ...............
	  ...............
      invisible(x)
  }

  setMethod("print", "mer", printMer)
  setMethod("show", "mer", function(object) printMer(object))


    RossB> Second, I read some advice somewhere, that I no
    RossB> longer can find, that show methods should return an
    RossB> object and that object in turn should be the thing
    RossB> that is printed.  I don't understand the motivation
    RossB> for that rule, at least in this case, because my
    RossB> object is already a results object.

I  think you're confusing show() with summary(): The latter is
should typically compute an object which then has a print/show method.


    RossB> The file promptClass creates has no methods in it.
    >> >> showMethods(classes="mspathCoefficients")
    RossB> Function: initialize (package methods)
    RossB> .Object="mspathCoefficients" (inherited from:
    RossB> .Object="ANY")
    >>  so it's just inherited from "ANY"
    >> 
    RossB> Function: print (package base) x="mspathCoefficients"
    >>  that's the one

    RossB> So why isn't promptClass picking it up?

    >>
    RossB> Function: show (package methods)
    RossB> object="mspathCoefficients" (inherited from:
    RossB> object="ANY")
    >> so it's just inherited from "ANY"
    >> 
    >> Ross, it would really be more polite to your readers if
    >> you followed the posting guide and posted complete
    >> fully-reproducible code...

    RossB> I thought it might be overkill in this case.  

It never is. We do want self-contained executable code..
In your case, I assumed it might have been things in a namespace
in a package, ...

    RossB> At any rate, it sounds as if I may be trying to do the wrong
    RossB> thing, so I'd appreciate guidance on what the right
    RossB> thing to do is.

    RossB> Here's a toy example:

    RossB> setClass("A", representation(x="numeric"))
    RossB> setMethod("print", signature(x="A"), function(x, ...) print(x at x, ...) )
    RossB> promptClass("A")

    RossB> The generated file has no print method.
 
Indeed, I can confirm that.

    >> >> getGeneric("print")
    RossB> standardGeneric for "print" defined from package
    RossB> "base"
    >> 
    RossB> function (x, ...)  standardGeneric("print")
    RossB> <environment: 0x84f2d88> Methods may be defined for
    RossB> arguments: x
    >> 
    >> 
    RossB> I've looked through the code for promptClass, but
    RossB> nothing popped out at me.
    >> 
    RossB> It may be relevant that I'm running under ESS in
    RossB> emacs.  However, I get the same results running R
    RossB> from the command line.
    >> 
    RossB> Can anyone tell me what's going on here?  This is
    RossB> with R 2.4, and I'm not currently using any namespace
    RossB> for my definitions.

    >> [and not a package either?]
    RossB> The code is part of  a package, but I'm developing code snippets in
    RossB> ESS without loading the whole package.
    >> 
    >> I'm very willing to look at this, once
    >> you've provided what the posting guide asks for, see above.

so now that I've promissed it; I'll have to look at it ;-)
Probably too late to get a fix into R 2.4.1 though.

Martin

    RossB> Thank you.  For completeness, here's some system info:

    >> sessionInfo()
    RossB> R version 2.4.0 (2006-10-03) 
    RossB> i486-pc-linux-gnu 

    RossB> locale:
    RossB> LC_CTYPE=en_US;LC_NUMERIC=C;LC_TIME=en_US;LC_COLLATE=en_US;LC_MONETARY=en_US;LC_MESSAGES=en_US;LC_PAPER=en_US;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US;LC_IDENTIFICATION=C

    RossB> attached base packages:
    RossB> [1] "methods"   "stats"     "graphics"  "grDevices" "utils"     "datasets" 
    RossB> [7] "base"     

    RossB> The Debian package is r-base-core 2.4.0.20061103-1.

    RossB> Ross



[Rd] promptClass misses methods
Martin Maechler