Hello all, An S4 class that contains matrix can be converted into a matrix using as(). When the resulting object is printed implicitly at the command line, all is well. When print() is explicitly called, I see an infinite recursion. Here is an example: ## create a subclass of matrix > setClass("Foo", representation(name="character"), contains="matrix") [1] "Foo" ## test it out > f <- new("Foo", name="Sam", matrix()) > z <- as(f, "matrix") > z [,1] [1,] NA > print(z) Error: evaluation nested too deeply: infinite recursion / options(expressions=)? An easy cut/paste version is below. I'm seeing this with an R 2.5.0 beta. I noticed that isS4(z) returns TRUE. This may or may not be surprising, but seems quite related to the issue at hand. + seth ## ----------------8<--------------8<----------------------- setClass("Foo", representation(name="character"), contains="matrix") f <- new("Foo", name="Sam", matrix()) f m <- as(f, "matrix") m print(m) ## ----------------8<--------------8<----------------------- -- Seth Falcon | Computational Biology | Fred Hutchinson Cancer Research Center http://bioconductor.org
John Chambers
2007-Apr-21 22:08 UTC
[Rd] infinite recursion when printing former S4 objects
Classes that contain "matrix" are trouble. Matrix objects are, well, weird. They look like they should be S3 classes but the object bit is not turned on and they have no class attribute. They seem to be recognized by much internal code on the basis of the "dim" attribute, so they appear to dispatch S3 methods, for example. They've been allowed as a data part in S4 class definitions, but it seems that we should perhaps retract that, unless it can be made to work reliably, which may not be possible without changing the semantics of matrix objects. The problems with class "Foo" are not just with printing. For example: > setClass("Foo", representation(name="character"), contains="matrix") [1] "Foo" > x = new("Foo", 1:12) Error: evaluation nested too deeply: infinite recursion / options(expressions=)? A little investigation pins this one down to as(x, "vector") <- Aside from these really nasty features, there is a problem with containing S3 classes in general, because the S3 dispatch can't recognize the new class as inheriting from the S3 class. For example: > bar = function(x)UseMethod("bar") > bar.matrix = function(x)"Matrix bar" > mm = matrix(1:12,3,4) > bar(mm) [1] "Matrix bar" > mF = new("Foo", mm) > bar(mF) Error in bar(mF) : no applicable method for "bar" > is.matrix(mF) [1] TRUE I do agree that the S4 bit should be turned off when an object drops down to having no class--it's something that doesn't seem to cause the same problems with inheritance from other basic data classes, though: > setClass("c2", representation(name = "character"), contains = "numeric") [1] "c2" > cc = new("c2", 1:12) > as(cc, "numeric") [1] 1 2 3 4 5 6 7 8 9 10 11 12 > cn = as(cc,"numeric") > class(cn) [1] "integer" > attr(cn, "class") NULL > isS4(cn) [1] TRUE > print(cn) [1] 1 2 3 4 5 6 7 8 9 10 11 12 John Seth Falcon wrote:> Hello all, > > An S4 class that contains matrix can be converted into a matrix using > as(). When the resulting object is printed implicitly at the command > line, all is well. When print() is explicitly called, I see an > infinite recursion. > > Here is an example: > > ## create a subclass of matrix > > setClass("Foo", representation(name="character"), contains="matrix") > [1] "Foo" > > ## test it out > > f <- new("Foo", name="Sam", matrix()) > > z <- as(f, "matrix") > > z > [,1] > [1,] NA > > print(z) > Error: evaluation nested too deeply: infinite recursion / options(expressions=)? > > An easy cut/paste version is below. I'm seeing this with an R 2.5.0 > beta. I noticed that isS4(z) returns TRUE. This may or may not be > surprising, but seems quite related to the issue at hand. > > > + seth > > > > ## ----------------8<--------------8<----------------------- > > setClass("Foo", representation(name="character"), contains="matrix") > f <- new("Foo", name="Sam", matrix()) > f > m <- as(f, "matrix") > m > print(m) > > ## ----------------8<--------------8<----------------------- > > >