>>>>> "WK" == Wacek Kusnierczyk <waclaw.marcin.kusnierc...@idi.ntnu.no> >>>>> on Mon, 23 Mar 2009 16:11:04 +0100 writes:
WK> Martin Maechler wrote: >> >> [...... omitted part no longer relevant ........] >> WK> however, the following has a different pattern: >> >> WK> x = NULL WK> dput(x) WK> # NULL WK> names(x) = character(0) WK> # error: attempt to set an attribute on NULL >> >> >> WK> i get the error in devel. >> >> Yes, NULL is NULL is NULL ! Do read ?NULL ! [ ;-) ] >> >> more verbously, all NULL objects in R are identical, or as the >> help page says, there's only ``*The* NULL Object'' in R, >> i.e., NULL cannot get any attributes. >> WK> yes, but that's not the issue. the issue is that names(x)<- seems to WK> try to attach an attribute to NULL, while it could, in principle, do the WK> same as class(x)<-, i.e., coerce x to some type (and hence attach the WK> name attribute not to NULL, but to the coerced-to object). yes, it could; but really, the fact that 'class<-' works is the exception. The other variants (with the error message) are the rule. WK> but, as someone else explained to me behind the scenes, the matters are WK> a little bit, so to speak, untidy: WK> x = NULL WK> class(x) = 'integer' WK> # just fine WK> x = NULL WK> attr(x, 'class') = 'integer' WK> # no go WK> where class()<-, but not attr(,'class')<-, will try to coerce x to an WK> object of the storage *mode* 'integer', hence the former succeeds WK> (because it sets, roughly, the 'integer' class on an empty integer WK> vector), while the latter fails (because it tries to set the 'integer' WK> class on NULL itself). WK> what was not clear to me is not why setting a class on NULL fails here, WK> but why it is setting on NULL in the first place. after all, WK> x = 1 WK> names(x) = 'foo' WK> is setting names on a *copy* of 1, not on *the* 1, so why could not WK> class()<- create a 'copy' of NULL, i.e., an empty vector of some type WK> (perhaps raw, as the lowest in the hierarchy). yes, it could. I personally don't think this would add any value to R's behavior; rather, for most useRs I'd think it rather helps to get an error in such a case, than a raw(0) object. Also, note (here and further below), that Using "class(.) <- <className>" is an S3 idiom and S3 classes ``don't really exist'', the "class" attribute being a useful hack, and many of us would rather like to work and improve working with S4 classes (& generics & methods) than to fiddle with 'class<-'. In S4, you'd use setClass(.), new(.) and setAs(.), typically, for defining and changing classes of objects. But maybe I have now lead you into a direction I will later regret, .... when you start telling us about the perceived inconsistencies of S4 classes, methods, etc. BTW: If you go there, please do use R 2.9.0 (or newer) exclusively. WK> x = c() WK> dput(x) WK> # NULL WK> names(x) = character(0) WK> # error: attempt to set an attribute on NULL >> >> >> WK> i get the error in devel. >> >> of course! >> [I think *you* should have noticed that NULL and c() *are* identical] >> WK> and also: >> >> WK> x = c() WK> class(x) = 'integer' WK> # fine >> "fine" yes; >> here, the convention has been to change NULL into integer(0); >> and no, this won't change, if you find it inconsistent. >> WK> that's ok, this is what i'd expect in the other cases, too (modulo the WK> actual storage mode). >> WK> class(x) = 'foo' WK> # error: attempt to set an attribute on NULL >> >> >> WK> i get the error in devel. >> >> No, not if you evaluate the statements above (where 'x' has >> become 'integer(0)' in the mean time). >> >> But yes, you get in something like >> >> x <- c(); class(x) <- "foo" >> WK> that's what i meant, must have forgotten the x = c(). >> and I do agree that there's a buglet : >> The error message should be slightly more precise, >> --- improvement proposals are welcome --- >> but an error nontheless >> WK> it doesn't seem coherent to me: why can i set the class, >> >> you cannot set it, you can *change* it. >> WK> terminological wars? WK> btw. the class of NULL is "NULL"; why can't nullify an object by WK> setting its class to 'NULL'? WK> x = 1 WK> class(x) = 'NULL' WK> x WK> # *not* NULL see above {S4 / S3 / ...}; If you want to "nullify", rather use more (S-language) idiomatic calls like as(x, "NULL") or as.null(x) both of which do work. Regards, Martin WK> and one more interesting example: WK> x = 1:2 WK> class(x) = 'NULL' WK> x WK> # [1] 1 2 WK> # attr(,"class") "NULL" WK> x[1] WK> # 1 WK> x[2] WK> # 2 WK> is.vector(x) WK> # FALSE WK> hurray!!! apparently, i've alchemized a non-vector vector... (you can WK> do it in r-devel, for that matter). WK> but not names WK> attribute on both NULL and c()? why can i set the class attribute to WK> 'integer', but not to 'foo', as i could on a non-empty vector: >> WK> x = 1 WK> class(x) = 'foo' WK> # just fine >> >> mainly because 'NULL is NULL is NULL' >> (NULL cannot have attributes) >> WK> yes yes yes; the question was, once again: why is x still NULL? WK> i'd naively expect to be able to create an empty vector classed 'foo', >> >> yes, but that expectation is wrong >> WK> wrt. the actual state of matters, not necessarily wrt. the ideal state WK> of matters ;) (i don't insist) WK> vQ ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel