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")
[EMAIL PROTECTED]<-"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.

______________________________________________
[EMAIL PROTECTED] 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: [EMAIL PROTECTED] ---W-W----
[EMAIL PROTECTED]







--
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: [EMAIL PROTECTED] ---W-W----
[EMAIL PROTECTED]


______________________________________________
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to