[Rd] S4 coercion responsibility

Seth Falcon seth at userprimary.net
Mon Sep 15 19:07:41 CEST 2008

* On 2008-09-15 at 08:56 -0400 Paul Gilbert wrote:
> Should functions or the user be responsible for coercing an S4 object 
> argument containing the proper object (and thus should below be 
> considered a bug in the packages or not)?
> The example is  with RSQLite but the same thing happens with RMySQL, and 
> other DBI packages.
> > library("RSQLite")  Loading required package: DBI
> > m <- dbDriver("SQLite")
> > con <- dbConnect(m)
> > setClass("SQLConPlus", contains=c("SQLiteConnection","integer"))
> [1] "SQLConPlus"
> > conPlus <- new("SQLConPlus", con, 1)
> > dbListTables(con)
> character(0)
> > dbListTables(conPlus)
> Error in sqliteExecStatement(con, statement, bind.data) :
> RS-DBI driver: (invalid dbManager handle)
> > dbListTables(as(conPlus, "SQLiteConnection"))
> character(0)
> >
> The problem is happening in sqliteExecStatement which does
>   conId <- as(con, "integer")
> but con only *contains* an SQLiteConnection and the other integer
> causes confusion. If the line were
>   conId <- as(as(con, "SQLiteConnection"), "integer")
> everything works.
> I can work around this, but I am curious where  responsibility for this 
> coercion should be.

Well, you've created a class that is-a SQLiteConnection *and* is-a
integer.  The fact that the as() method dispatch doesn't match that of
SQLiteConnection should really be that surprising.

I don't see how this could be the responsibility of the author of the
class you've subclassed.

I would also question why SQLConPlus is extending integer.  That seems
like a very strange choice.  Why not extend SQLiteConnection and add
extra slots as you like.  The dispatch will in this case be much
easier to reason about.

+ seth

Seth Falcon | http://userprimary.net/user/

More information about the R-devel mailing list