I looked through the documentation and the mailing lists and could not find an answer to this. My apologies if it has already been answered. If it has, a pointer to the relevant discussion would be greatly appreciated. Creating S4 classes containing environments exhibits unexpected behavior/features.? These have a different in two ways: 1) slotName for the data: ".xData" instead of ".Data" and do not respond to the 2) Response to the is.* function seems to indicate that the object does not know of its inheritance. ( Notably, the inherits function works as expected. ) Here is a working illustration:> # LIST > setClass( 'inheritList', contains='list')[1] "inheritList"> inList <- new( 'inheritList' ) > class( inList )[1] "inheritList" attr(,"package") [1] ".GlobalEnv"> is.list( inList ) # TRUE[1] TRUE> slotNames(inList) # ".Data"[1] ".Data"> inherits(inList, 'list' ) # TRUE[1] TRUE> > > # ENVIRONMENT > setClass( 'inheritEnv', contains='environment' )Defining type "environment" as a superclass via class ".environment" [1] "inheritEnv"> inEnv <- new( 'inheritEnv' ) > class(inEnv)[1] "inheritEnv" attr(,"package") [1] ".GlobalEnv"> is.environment(inEnv) # FALSE[1] FALSE> slotNames(inEnv) # ".xData"[1] ".xData"> inherits(inEnv, 'environment' ) # TRUE[1] TRUE My questions is whether this behavior is a bug? By design? A work around? Etc.? Thanks kindly for your reply, Chris the Open Data Group ?http://www.opendatagroup.com ?http://blog.opendatagroup.com
I think using 'is(inEnv, "environment")' produces the answer you expect. Can't explain the other anomalies though. -roger On Sat, Apr 24, 2010 at 1:15 PM, Christopher Brown <cbrown at opendatagroup.com> wrote:> I looked through the documentation and the mailing lists and could not > find an answer to this. ?My apologies if it has already been answered. > ?If it has, a pointer to the relevant discussion would be greatly > appreciated. > > Creating S4 classes containing environments exhibits unexpected > behavior/features.? These have a different in two ways: > > 1) slotName for the data: ".xData" instead of ".Data" and do not respond to the > 2) Response to the is.* function seems to indicate that the object > does not know of its inheritance. ?( Notably, the inherits function > works as expected. ) > > Here is a working illustration: > >> # ?LIST >> setClass( 'inheritList', contains='list') > [1] "inheritList" >> inList <- new( 'inheritList' ) >> class( inList ) > [1] "inheritList" > attr(,"package") > [1] ".GlobalEnv" >> is.list( inList ) ? ? ? ? ?# TRUE > [1] TRUE >> slotNames(inList) ? ? ? ? ?# ".Data" > [1] ".Data" >> inherits(inList, 'list' ) ?# TRUE > [1] TRUE >> >> >> # ENVIRONMENT >> setClass( 'inheritEnv', contains='environment' ) > Defining type "environment" as a superclass via class ".environment" > [1] "inheritEnv" >> inEnv <- new( 'inheritEnv' ) >> class(inEnv) > [1] "inheritEnv" > attr(,"package") > [1] ".GlobalEnv" >> is.environment(inEnv) ? ? ? ? ? ? # FALSE > [1] FALSE >> slotNames(inEnv) ? ? ? ? ? ? ? ? ?# ".xData" > [1] ".xData" >> inherits(inEnv, 'environment' ) ? # TRUE > [1] TRUE > > My questions is whether this behavior is a bug? By design? ?A work > around? ?Etc.? > > Thanks kindly for your reply, > > Chris > > > the Open Data Group > ?http://www.opendatagroup.com > ?http://blog.opendatagroup.com > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Roger D. Peng | http://www.biostat.jhsph.edu/~rpeng/
On 24/04/2010 1:15 PM, Christopher Brown wrote:> I looked through the documentation and the mailing lists and could not > find an answer to this. My apologies if it has already been answered. > If it has, a pointer to the relevant discussion would be greatly > appreciated. >Environments are unusual in that they are reference objects: if e is an environment, and you assign f <- e, then f refers to the same object as e does. This is unusual in R, where most objects are copied on assignment (logically, not always physically). It means that attributes on environments behave strangely: if you put an attribute on e and remove the same attribute from f, it is gone from e too. We've discussed removing the possibility of putting attributes on environments (just as you can't put attributes on NULL), but haven't done so yet. What you should do if you want to use an environment in the way you're using it is to put it in a container. For S4, that could mean using an environment as a slot, or inheriting from an object like list(e), rather than directly from e. Duncan Murdoch> Creating S4 classes containing environments exhibits unexpected > behavior/features. These have a different in two ways: > > 1) slotName for the data: ".xData" instead of ".Data" and do not respond to the > 2) Response to the is.* function seems to indicate that the object > does not know of its inheritance. ( Notably, the inherits function > works as expected. ) > > Here is a working illustration: > > >> # LIST >> setClass( 'inheritList', contains='list') >> > [1] "inheritList" > >> inList <- new( 'inheritList' ) >> class( inList ) >> > [1] "inheritList" > attr(,"package") > [1] ".GlobalEnv" > >> is.list( inList ) # TRUE >> > [1] TRUE > >> slotNames(inList) # ".Data" >> > [1] ".Data" > >> inherits(inList, 'list' ) # TRUE >> > [1] TRUE > >> # ENVIRONMENT >> setClass( 'inheritEnv', contains='environment' ) >> > Defining type "environment" as a superclass via class ".environment" > [1] "inheritEnv" > >> inEnv <- new( 'inheritEnv' ) >> class(inEnv) >> > [1] "inheritEnv" > attr(,"package") > [1] ".GlobalEnv" > >> is.environment(inEnv) # FALSE >> > [1] FALSE > >> slotNames(inEnv) # ".xData" >> > [1] ".xData" > >> inherits(inEnv, 'environment' ) # TRUE >> > [1] TRUE > > My questions is whether this behavior is a bug? By design? A work > around? Etc.? > > Thanks kindly for your reply, > > Chris > > > the Open Data Group > http://www.opendatagroup.com > http://blog.opendatagroup.com > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
In addition to Duncan Murdoch's explanation, this is discussed in the documentation for "Classes" (briefly): ..... Extending a basic type this way allows objects to use old-style code for the corresponding type as well as S4 methods. Any basic type can be used for .Data, but a few types are treated differently because they do not behave like ordinary objects; for example, "NULL", environments, and external pointers. Classes extend these types by using a specially named slot, itself inherited from an internally defined S4 class. Inheritance from the nonstandard object type then requires an actual computation, rather than the "simple" inclusion for other types and classes. The intent is that programmers will not need to take account of the mechanism, but one implication is that you should not explicitly use the type of an S4 object that extends an arbitrary object type. Use is and similar functions instead. ....... The code for is.environment() is presumably using the type, whereas inherits() takes account of the indirect mechanism. Generally, you should be able to deal with inheritance from environments in a natural way. John On 4/24/10 10:15 AM, Christopher Brown wrote:> I looked through the documentation and the mailing lists and could not > find an answer to this. My apologies if it has already been answered. > If it has, a pointer to the relevant discussion would be greatly > appreciated. > > Creating S4 classes containing environments exhibits unexpected > behavior/features. These have a different in two ways: > > 1) slotName for the data: ".xData" instead of ".Data" and do not respond to the > 2) Response to the is.* function seems to indicate that the object > does not know of its inheritance. ( Notably, the inherits function > works as expected. ) > > Here is a working illustration: > >> # LIST >> setClass( 'inheritList', contains='list') > [1] "inheritList" >> inList<- new( 'inheritList' ) >> class( inList ) > [1] "inheritList" > attr(,"package") > [1] ".GlobalEnv" >> is.list( inList ) # TRUE > [1] TRUE >> slotNames(inList) # ".Data" > [1] ".Data" >> inherits(inList, 'list' ) # TRUE > [1] TRUE >> >> >> # ENVIRONMENT >> setClass( 'inheritEnv', contains='environment' ) > Defining type "environment" as a superclass via class ".environment" > [1] "inheritEnv" >> inEnv<- new( 'inheritEnv' ) >> class(inEnv) > [1] "inheritEnv" > attr(,"package") > [1] ".GlobalEnv" >> is.environment(inEnv) # FALSE > [1] FALSE >> slotNames(inEnv) # ".xData" > [1] ".xData" >> inherits(inEnv, 'environment' ) # TRUE > [1] TRUE > > My questions is whether this behavior is a bug? By design? A work > around? Etc.? > > Thanks kindly for your reply, > > Chris > > > the Open Data Group > http://www.opendatagroup.com > http://blog.opendatagroup.com > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >