From wolski at molgen.mpg.de  Wed Sep 29 22:23:37 2004
From: wolski at molgen.mpg.de (Witold Eryk Wolski)
Date: Wed Sep 29 22:23:54 2004
Subject: [Rd] Problem with _new_ if class "lm" in object representation.
In-Reply-To: <415B0E2A.1EB9FE80@research.bell-labs.com>
References: <200409291920310735.30925C98@mail.math.fu-berlin.de>
	<415AFBEB.8C1F58B4@research.bell-labs.com>
	<415B085A.9010109@molgen.mpg.de>
	<415B0E2A.1EB9FE80@research.bell-labs.com>
Message-ID: <415B19C9.4020403@molgen.mpg.de>

Hi,

Thanks a lot for pointing me to setOldClass().

What is exactly the point against it, to allow NULL to be a special case 
which can be assigned to any slot? I think in java one can assing null 
to any slot (I do not like java but not because of that).
I am asking because for some objects it may be hard to define something 
equivalent to numeric(0). And even lm(1~1) is not that what I am looking 
for. I would like to have the case
of an unassigned slot (Just think about storage?) even to the expense 
checking every time if the slot is not null.


There are of course more solutions. Since the validity method is not 
called  I can do:
dd<-new("Ctest")
dd@test<-"bla"

Or of course as you have mentioned to write an initialization method. 
But this points me to a further question.
How to write a good initialization method which covers all possible 
cases? In programming languages like C and java you can provide 
different types of constructors.
But in S4 you can provide just one method initialize?
How to handle for example

new("Ctest",mod=lm(1~1))
new("Ctest",test="bla")
new("Ctest",bla="brum")
and
new("Ctest",test="bla",bla="brum")

within one initialization function? Using match.call? missing is not 
enough I think.


/E

setClass("Ctest"
	,representation(
		test="character"
		,bla="character"
		,mod="lm" 
		)
	)
	



John Chambers wrote:

>Witold Eryk Wolski wrote:
>  
>
>>Hi,
>>The hint to use an lm0 instance in the protopy is a solution.
>>
>>But I thought about a different solution to which I got used. This is to
>>declare class "lm" as an S4 class by setClass("lm"). 
>>    
>>
>
>It's a good idea to declare S3 classes, but that's not the way to do
>it.  If you want to use an S3 class as an S4 class, that's what
>setOldClass() is for.  See the green book or the documentation.
>
>Why doesn't that work for "lm"?   As the error message says below, "lm"
>is already defined in this way & sealed, just as other standard classes
>are sealed.
>
>This is NOT a solution to your previous problem, however, since it's
>still totally unknown what a default object from an S3 class should be
>like.
>
>You will still get an error from new("Ctest", test = "bla") if you have
>an undefined slot from an S3 class, or any other VIRTUAL class.  (It
>happens that new("Ctest") doesn't fail because if there are no arguments
>to new() other than the class name, the validity method isn't called.)
>
>Your "working" solution doesn't work, as in the following simpler
>example:
>
>R> setClass("bar")
>[1] "bar"
>R> setClass("foo", representation(x="numeric", y="bar"))
>R> new("foo", x=1)
>Error in validObject(.Object) : Invalid "foo" object: Invalid object for
>slot "y" in class "foo": got class "NULL", should be or extend class
>"bar"
>
>(We should in fact warn on the call to setClass() in this case, since
>the protoype object is not a valid object from the class.  For 2.0.1)
>
>  
>
>>This is because I
>>have to do it anyway quite frequently when using S3 classes, declared
>>in contributed packages, in S4 classes.
>>Please consider the following code with this quite recent version
>>generating a warning.
>>R : Copyright 2004, The R Foundation for Statistical Computing
>>Version 2.0.0 beta (2004-09-20), ISBN 3-900051-07-0
>>
>>#I like to have an object which  contains an object of class fields:Krig.
>>
>>library(fields)
>>
>>setClass("Ctest"
>>        ,representation(
>>                test="character"
>>                ,bla="character"
>>                ,mod="Krig"
>>                )
>>        )
>>
>>#Warning message:
>>#Undefined slot classes in definition of "Ctest": mod (class " Krig ") in: .completeClassSlots(ClassDef, where)
>>
>>The overcome this warning i just modify the code adding
>>
>>setClass("Krig")
>>setClass("Ctest"
>>        ,representation(
>>....
>>
>>previous to defining class Ctest.
>>This is my working solution. But this one does not work with class "lm".
>>Since,
>>
>> > setClass("lm")
>>Error in setClass("lm") : "lm" has a sealed class definition and cannot
>>be redefined
>>
>>I understand the errror message but I can't see the difference between
>>class Krig and lm which are both S3 classes. (of course except that lm
>>is in in THE stats package)
>>Is it intended to keep two different "models" of treating S3 classes?
>>One for S3 class from the recomended, "base" packages and a different
>>one for S3 classes from contributed packages? I assume not.
>>If, so I feel a alienated because my code so far rely on the behaviour
>>which I observed for S3/contributed classes.
>>
>>/E,
>>
>>John Chambers wrote:
>>
>>    
>>
>>>Wolski wrote:
>>>
>>>
>>>      
>>>
>>>>Hi!
>>>>Consider this code.
>>>>
>>>>setClass("Ctest"
>>>>       ,representation(
>>>>               test="character"
>>>>               ,bla="character"
>>>>               ,mod="lm"
>>>>               )
>>>>       )
>>>>
>>>>new("Ctest",test="bla")                     #This produces an error.
>>>>
>>>>#Error in validObject(.Object) : Invalid "Ctest" object: Invalid object for slot "mod" in class "Ctest": got class "NULL", should be or extend class "lm"
>>>>
>>>>
>>>>        
>>>>
>>>And the error message is correct.  Since "lm" is an S3 class, there is
>>>no way to generate an object automatically from it.  new("lm") will also
>>>produce an error.
>>>
>>>If you want objects to be generated from your class with a default "lm"
>>>object, you have to first decide what that is.  Assuming you know, you
>>>need to either put that element into the protoype for the class, or have
>>>a method for initialize() that does something sensible, using the rest
>>>of the data in the object.
>>>
>>>The prototype solution could look something like:
>>>
>>>R> lm0 = lm(1~1)
>>>R> setClass("Ctest", representation(test = "character",
>>>   bla = "character", mod = "lm"), prototype=prototype(mod = lm0))
>>>R> new("Ctest", test="bla")
>>>An object of class "Ctest"
>>>Slot "test":
>>>[1] "bla"
>>>
>>>Slot "bla":
>>>character(0)
>>>
>>>Slot "mod":
>>>
>>>Call:
>>>lm(formula = 1 ~ 1)
>>>
>>>Coefficients:
>>>(Intercept)
>>>         1
>>>
>>>
>>>There is no automatic relation between the class "lm" and the function
>>>lm().  The green book recommends having a generator function, but the R
>>>code can't assume this has been done.
>>>
>>>
>>>
>>>      
>>>
>>>>setClass("Ctest"
>>>>       ,representation(
>>>>               test="character"
>>>>               ,bla="character"
>>>>               ,mod="character"                # its the only with the class definition above.
>>>>       )
>>>>       )
>>>>new("Ctest",test="bla")                         #this works as I would expect.
>>>>
>>>>#An object of class "Ctest"
>>>>#Slot "test":
>>>>#[1] "bla"
>>>>#
>>>>#Slot "bla":
>>>>#character(0)
>>>>#
>>>>#Slot "mod":
>>>>#character(0)
>>>>
>>>>Thought that this is due to that the class lm has no lm(0) object. Hence i tried
>>>>
>>>>setClass("brum",representation(brum="brum"))
>>>>setClass("Ctest"
>>>>       ,representation(
>>>>               test="character"
>>>>               ,bla="character"
>>>>               ,mod="brum"                # its the only with the class definition above.
>>>>       )
>>>>       )
>>>>
>>>>new("Ctest",test="best")  #but this works to.
>>>>
>>>>______________________________________________
>>>>R-devel@stat.math.ethz.ch mailing list
>>>>https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>
>>>>
>>>>        
>>>>
>>>
>>>      
>>>
>>--
>>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
>>    
>>
>
>  
>


-- 
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


[Rd] Problem with _new_ if class "lm" in object representation.
Witold Eryk Wolski