From pgilbert at bank-banque-canada.ca  Wed Jul 18 17:39:27 2007
From: pgilbert at bank-banque-canada.ca (Paul Gilbert)
Date: Wed, 18 Jul 2007 11:39:27 -0400
Subject: [Rd] S4 coerce
In-Reply-To: <469CD0B8.5030301@bank-banque-canada.ca>
References: <469B8771.5060601@bank-banque-canada.ca>
	<m2fy3nipp7.fsf@ziti.fhcrc.org>
	<469CD0B8.5030301@bank-banque-canada.ca>
Message-ID: <469E342F.5030103@bank-banque-canada.ca>

This may be a better example of what I am now thinking is probably a bug 
in S4 dispatch:

 > require("RMySQL") # or require("RSQLite")
Loading required package: RMySQL
Loading required package: DBI
[1] TRUE

 > m <- dbDriver("MySQL")  # or  m <- dbDriver("SQLite")
 > con <- dbConnect(m, dbname="test")
 >dbGetQuery(con, "create table zzz (
   vintage     VARCHAR(20) NOT NULL,
   alias       VARCHAR(20) default NULL,
   Documentation     TEXT,
   PRIMARY KEY (vintage)
   );")

 >dbListTables(con)
 [1] "zzz"                 

 > setClass("TSconnection", contains="DBIConnection",
    representation(con="DBIConnection",
    vintage = "logical",
    panel   = "logical"))
[1] "TSconnection"

 > setAs("TSconnection", "DBIConnection", def = function(from) from at con)
[1] "coerce<-"

 > setIs("TSconnection", "DBIConnection", coerce = function(x) x at con)
Warning message:
there is no automatic definition for as(object, "DBIConnection") <- 
value when object has class "TSconnection" and no 'replace' argument was 
supplied; replacement will be an error in: makeExtends(class1, class2, 
coerce, test, replace, by, classDef1 = classDef, 

 > Tcon <- new("TSconnection", con=dbConnect(m, dbname="test"), 
vintage=FALSE, panel=FALSE)

 > is(Tcon, "DBIConnection")
[1] TRUE

I think this should work:

 > dbListTables(Tcon)
Error in function (classes, fdef, mtable)  :
    unable to find an inherited method for function "dbListTables", for 
signature "TSconnection"

but instead I have to do this:

 > dbListTables(as(Tcon, "DBIConnection"))
 [1]  "zzz"                 
 
Paul

Paul Gilbert wrote:

>
>
> Seth Falcon wrote:
>
>> Paul Gilbert <pgilbert at bank-banque-canada.ca> writes:
>>
>>  
>>
>>> (I am not sure if this is a bug or a request for a more 
>>> understandable warning, or possible something obvious I should be 
>>> posting on r-help.)
>>>
>>> I am trying to coerce an new class object to be a DBIConnection and 
>>> it does not work the way I think it should:
>>>
>>> R version 2.5.1 (2007-06-27) ...
>>> > require("RMySQL") # or require("RSQLite")
>>> Loading required package: RMySQL
>>> Loading required package: DBI
>>> [1] TRUE
>>> > m <- dbDriver("MySQL")  # or  m <- dbDriver("SQLite")
>>> > con <- dbConnect(m, dbname="test")
>>> > dbGetQuery(con, "create table zzz (
>>> +    vintage     VARCHAR(20) NOT NULL,
>>> +    alias       VARCHAR(20) default NULL,
>>> +    Documentation     TEXT,
>>> +    PRIMARY KEY (vintage)
>>> +    );")
>>> NULL
>>> > dbListTables(con)
>>>  [1] "zzz"
>>> > setClass("TSconnection", representation(con="DBIConnection",
>>> +    vintage = "logical",
>>> +    panel   = "logical")
>>> +    )
>>> [1] "TSconnection"
>>> > setAs("TSconnection", "DBIConnection", def = function(from) from at con)
>>>   
>>
>>
>> I think things work as you expect up until this pint.
>>  
>>
> Yes.
>
>>  
>>
>>> > setIs("TSconnection", "DBIConnection", coerce = function(x)
>>> > x at con)
>>>   
>>
>>
>> I'm confused about what you want to do here.  If you want TSconnection
>> to be a DBIConnection, why wouldn't you use inheritance?
>>
>>   setClass("TSconnection", contains="DBIConnection", ...)
>>  
>>
> Perhaps my logic is confused, it wouldn't be the first time,  but I am 
> thinking of this as going the "other direction" from inheritance.   A 
> MySQLConnection or SQLiteConnection inherits from DBIConnection. To 
> actually use a DBIConnection or my TSconnection it will be necessary 
> to have one of these, so I would need something like
>
> setClass("TSconnection", contains="MySQLConnection", ...)
>
> to make this work. (Actually, I have not been able to make it work, 
> but that may just be the novice level of my experimenting.)   I am 
> hoping I can define the TSconnection using only DBIConnection classes 
> and have it automatically work when one of the database driver 
> packages is added. Otherwise  I have to define the TSconnection for 
> each of the driver packages, which is not as clean.
>
> Paul
>
>> + seth
>>
>>  
>>
====================================================================================

La version fran?aise suit le texte anglais.

------------------------------------------------------------------------------------

This email may contain privileged and/or confidential inform...{{dropped}}



[Rd] S4 coerce
Paul Gilbert