From jmc at research.bell-labs.com  Mon Oct 11 17:51:32 2004
From: jmc at research.bell-labs.com (John Chambers)
Date: Mon Oct 11 17:51:58 2004
Subject: [Rd] Function _coerce_ in _setIs_ never entered (S4).
References: <41664EA7.60007@molgen.mpg.de>
Message-ID: <416AAC04.B7E4099F@research.bell-labs.com>

The source of the problem is that, because "list" is a basic class,
there is a pre-defined method for as(x, "list") (roughly, use
as.list(x)).  (Technically, this is found as a method for the coerce()
function.)

Normally, setIs() doesn't explicitly set the method for coerce(),
delaying that until the first time as() is called for the corresponding
combination of classes.  Here, that doesn't work, because as() finds the
existing method and never looks for the new one.

The likely fix is to have setIs() check for an existing method or else
just always set the method, but the relevant code is sufficiently basic
that the fix needs to be checked fairly carefully before committing it.

Meanwhile, depending on what it is that you're really trying to do, a
workaround would be to use a special class instead of "list", a class
that had a list as a slot.

Also, notice that the problem is in trying for an _automatic_ coerce of
MVCa to "list".  As a design issue, it's fairly often the case that you
don't want that anyway.  As per the green book, using setIs() means that
your new class acts like a list in all respects, and often that's not
the case.  Using setAs() instead of setIs() would then be the better
choice.

Witold Eryk Wolski wrote:
> 
> Hi,
> 
> Please consider the following trivial example.
> In the sample code I first define a class MVCa using composition. This
> class contains a slot  of type list.
> Next I define an inheritance relation using the function setIs -> MVCa
> "is a" list.
> Then I define a function printlength which prints the list-length which
> is defined for the type "list".
> If I call this function assigning to their argument an object of class
> MVCa I would expect that the function _coerce_  defined in setIs will be
> called.
> It seems that this never happens using:
> R : Copyright 2004, The R Foundation for Statistical Computing
> Version 2.0.0 Patched (2004-10-04), ISBN 3-900051-07-0
> 
> setClass(
>          "MVCa"
>          ,representation(list="list"
>                          ,content="character")
>          ,prototype(content="numeric")
>          )
> 
> setIs("MVCa","list",coerce=function(obj){obj@list},replace=function(obj,value){obj@list<-value})
> 
> setGeneric("printlength",function(object,...)
> standardGeneric("printlength"))
> setMethod("printlength"
>           ,signature(object="list")
>           ,def=function(object)
>           {
>             print(length(object))
>           }
>           )
> 
> xx<-as.list(1:4)
> names(xx)<-letters[1:4]
> mvca<-new("MVCa")
> mvca@list<-xx
> 
> printlength(mvca)
> 
> Any suggestions?
> 
> /E
> 
> --
> Dipl. bio-chem. Witold Eryk Wolski
> MPI-Moleculare Genetic
> Ihnestrasse 63-73 14195 Berlin                 _
> tel: 0049-30-83875219                 __("<   'v'
> http://www.molgen.mpg.de/~wolski      \__/   /   \
> mail: witek96@users.sourceforge.net    ^^     w w
>       wolski@molgen.mpg.de
> 
> ______________________________________________
> R-devel@stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
John M. Chambers                  jmc@bell-labs.com
Bell Labs, Lucent Technologies    office: (908)582-2681
700 Mountain Avenue, Room 2C-282  fax:    (908)582-3340
Murray Hill, NJ  07974            web: http://www.cs.bell-labs.com/~jmc


[Rd] Function _coerce_ in _setIs_ never entered (S4).
John Chambers