From maechler at stat.math.ethz.ch  Fri Mar 23 17:53:09 2007
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Fri, 23 Mar 2007 17:53:09 +0100
Subject: [Rd] Bug in str or issue with class management in my package?
In-Reply-To: <9637517.post@talk.nabble.com>
References: <9633559.post@talk.nabble.com> <6phzm646rn3.fsf@gopher4.fhcrc.org>
	<9637517.post@talk.nabble.com>
Message-ID: <17924.1525.361430.93301@stat.math.ethz.ch>

Hi,

>>>>> "Ulrike" == Ulrike Gr?mping <groemp at tfh-berlin.de>
>>>>>     on Fri, 23 Mar 2007 08:39:32 -0700 (PDT) writes:

    Ulrike> Martin,

    Ulrike> thank you, you've pointed me in the right direction! I just wasn't aware
    Ulrike> that a slot must not be unassigned (everything but str worked so far, and
    Ulrike> even str works in R 2.3.1). 

That "everything worked" is actually quite astonishing to me.

I'd have expected that you should get an *error* when using

  class(<S4-object>) <- "arbitraryString"

since - as Martin Morgan mentioned - you typically coerce
S4 objects to a new class by  as(<..>, "new class")
                              ~~~~~~~~~~~~~~~~~~~~~
[ which either needs an explicit  SetAs(from,to, ....)
  declaration ``earlier on'' (typically by one of the class
  designers, often package authors),
  or an implicit one - as in your case, when one class extends
  another ]

Martin M?chler, ETH Zurich



    Ulrike> Actually, looking up the help for function new, I see that the solution is
    Ulrike> much easier, because my class relimplmbooteval extends the class relimplm of
    Ulrike> the object ausgabe. Therefore, I can simply write 
    Ulrike> obj <- new("relimplmbooteval", ausgabe)
    Ulrike> which copies all slots from ausgabe to the right place in the new obj.

    Ulrike> Regards, Ulrike


    Ulrike> Martin Morgan wrote:
    >> 
    >> Ulrike,
    >> 
    >> booteval.relimp has the statement
    >> 
    >> ausgabe <- calc.relimp(empcov, type = type, diff = diff, 
    >> rank = rank, rela = rela, always = always, groups = groups, 
    >> groupnames = groupnames)
    >> class(ausgabe) <- "relimplmbooteval"
    >> 
    >> This changes the name of the class of ausgabe, without changing its
    >> structure. I'm guessing that prior to this call ausgabe did not have a
    >> slot "pmvd.lower". Here's the simpler version:
    >> 
    >>> setClass("A", representation=representation(x="numeric"))
    >> [1] "A"
    >>> setClass("B", contains="A", representation=representation(y="numeric"))
    >> [1] "B"
    >>> a <- new("A")
    >>> class(a) <- "B"
    >>> str(a)
    >> Error in FUN(c("y", "x")[[1L]], ...) : no slot of name "y" for this object
    >> of class "B"
    >> 
    >> and some behavior which is somehow weird:
    >> 
    >>> slot(a, "y")
    >> Error in slot(a, "y") : no slot of name "y" for this object of class "B"
    >>> slot(a, "y") <- 10 # 'creates' the slot!
    >>> slot(a, "y")
    >> [1] 10
    >> 
    >> Probably what you want to do is to create a 'setAs' method
    >> 
    >> setAs('relimplm', 'relimplmbooteval',
    >> function(from) {
    >> <your code here, e.g.,>
    >> })
    >> 
    >> and use
    >> 
    >> ausgabe <- as(ausgabe, "relimplmbooteval")
    >> 
    >> I'm not really sure what <your code here> should look like; my first
    >> stab was
    >> 
    >> obj <- new("relimplmbooteval")
    >> slots <- slotNames(from)
    >> for (slt in slots)
    >> slot(obj, slt) <- slot(from, slt)
    >> obj
    >> 
    >> which would not be very memory efficient (each slot assignment copies
    >> the entire object) but is perhaps fine for your needs.
    >> 
    >> Hope that helps
    >> 
    >> Martin
    >> 
    >> Ulrike Gr?mping <groemp at tfh-berlin.de> writes:
    >> 
    >>> Dear developeRs,
    >>> 
    >>> with R 2.4.1 (and also 2.4.0), the function str() fails on objects of
    >>> class
    >>> relimplmbooteval, if there are unused slots, which is very often the
    >>> case. I
    >>> am not sure whether this is a bug in str() or a correct behavior of str()
    >>> that unmasks some sloppiness in my usage of S4 classes (that I am not
    >>> aware
    >>> of)?
    >>> 
    >>> Reproducible example (package relaimpo needed):
    >>> 
    >>> The program 
    >>> 
    >>> require(relaimpo)
    >>> bte<-booteval.relimp(boot.relimp(swiss,b=100))
    >>> str(bte)
    >>> 
    >>> yields the error message
    >>> 
    >>> Errorr in FUN(c("lmg.lower", "lmg.upper", "lmg.rank.lower",
    >>> "lmg.rank.upper",  : 
    >>> no slot named "pmvd.lower" for this object of class
    >>> "relimplmbooteval"
    >>> (back-translated from German).
    >>> 
    >>> Regards, Ulrike
    >>> -- 
    >>> View this message in context:
    >>> http://www.nabble.com/Bug-in-str-or-issue-with-class-management-in-my-package--tf3453429.html#a9633559
    >>> Sent from the R devel mailing list archive at Nabble.com.
    >>> 
    >>> ______________________________________________
    >>> R-devel at r-project.org mailing list
    >>> https://stat.ethz.ch/mailman/listinfo/r-devel
    >> 
    >> -- 
    >> Martin Morgan
    >> Bioconductor / Computational Biology
    >> http://bioconductor.org
    >> 
    >> ______________________________________________
    >> R-devel at r-project.org mailing list
    >> https://stat.ethz.ch/mailman/listinfo/r-devel
    >> 
    >> 

    Ulrike> -- 
    Ulrike> View this message in context: http://www.nabble.com/Bug-in-str-or-issue-with-class-management-in-my-package--tf3453429.html#a9637517
    Ulrike> Sent from the R devel mailing list archive at Nabble.com.

    Ulrike> ______________________________________________
    Ulrike> R-devel at r-project.org mailing list
    Ulrike> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Bug in str or issue with class management in my package?
Martin Maechler