[R-pkg-devel] S3 length method behavior

Barry Rowlingson b.rowlingson at lancaster.ac.uk
Tue Feb 2 18:23:46 CET 2016


On Tue, Feb 2, 2016 at 3:28 PM, Hadley Wickham <h.wickham at gmail.com> wrote:
> I've found that it's a very bad idea to provide length or names
> methods for just this reason.


>> After looking
>> for memory leaks and other errors I finally noticed that the str() on the
>> object of myClass looked odd. It returned something like this:
>>
>> List of 82
>>  $ file  : chr "my/file/location"
>>  $ handle:<externalptr>
>>  $ NA:
>> Error in object[[i]] : subscript out of bounds


>> My questions are, then, whether this behavior makes sense and what to do
>> about it. If I define my own str() method, will that fix it? I think I am
>> just misunderstanding what is going on with the methods I have defined.
>> Hopefully, someone can offer some clarity.

 Defining a str on your class will at least fix the out of bounds error:

Create a trivial S3 class:

 > z=list(1,22)
 > class(z)="foo"

length method looks at the second element:

 > length.foo=function(x){x[[2]]}
 > length(z)
[1] 22

 and str barfs:

 > str(z)
List of 22
 $ : num 1
 $ : num 22
 $ :Error in object[[i]] : subscript out of bounds

Define a str method:

 > str.foo=function(object,...){for(i in
1:length(unclass(object))){str(unclass(object[[i]]))}}
 > str(z)
 num 1
 num 22

BUT... the real problem is that S3 classes are seriously informal and
there's no concept of what methods you need to define on a class
because there's no concept of an "interface" that new classes have to
conform to. So stuff breaks, seemingly at random, and via action at a
distance. Somewhere something is going to expect z[[1]] to
z[[length(z)]] to exist, which is what the default str is doing...

+1 on Hadley - don't override any basic R structural methods, create
new ones with new names. You can make them more meaningful too. For
your example, maybe "messageCount(myObject)"?

Barry



More information about the R-package-devel mailing list