John

Here is the definition of the TSMySQLConnection class, and a few other things. This is a simplified example that produces the message, but unfortunately will not work unless you have a MySQL database to connect to. (I do get the same problem with PostgreSQL, and may with SQLLite, but I have not tested the last yet.)

require("methods")
require("DBI")
require("RMySQL")

setClassUnion("OptionalPOSIXct",   c("POSIXct",   "logical"))
setClass("conType", representation( drv="character"), "VIRTUAL" )

setClass("TSdb", representation( dbname="character",
    hasVintages="logical", hasPanels="logical"), "VIRTUAL" )


setClass("TSMySQLConnection", contains=c("MySQLConnection", "conType", "TSdb"))


setGeneric("TSconnect", def= function(drv, dbname, ...) standardGeneric("TSconnect"))


setMethod("TSconnect",   signature(drv="MySQLDriver", dbname="character"),
   definition=function(drv, dbname, ...) {
        con <- dbConnect(drv, dbname=dbname, ...)
        new("TSMySQLConnection" , con, drv="MySQL", dbname=dbname,
               hasVintages=dbExistsTable(con, "vintageAlias"),
               hasPanels  =dbExistsTable(con, "panels"))
        })

con <- TSconnect(dbDriver("MySQL"), "test")

dbGetQuery(con, "show tables")
Note: Method with signature "MySQLConnection#integer" chosen for function "coerce",
 target signature "TSMySQLConnection#integer".
 "dbObjectId#integer" would also be valid
   Tables_in_test
1               A
2               B
>

The message also seems to go away, even quitting R and restarting to clear the cache, if I change the TSconnect method as follow

setMethod("TSconnect",   signature(drv="MySQLDriver", dbname="character"),
   definition=function(drv, dbname, ...) {
        con <- dbConnect(drv, dbname=dbname, ...)
        new("TSMySQLConnection" , con, drv="MySQL", dbname=dbname,
               hasVintages=FALSE,
               hasPanels  =FALSE)
        })

Why this would happen makes absolutely no sense to me. In the first version is dbExistsTable(con, "vintageAlias") left unevaluated in the result from new?

As you can tell, I'm struggling a bit with interpreting the information from the note. Also, if it were a warning I could set it to stop, and then traceback to what was causing the problem. As it is, it took me a fairly long time just to get the fact that the call to dbGetQuery() was generating the message. And caching the methods may be good for performance, but when things change the second time you call them it sure makes debugging difficult.

Best,
Paul


On 12-03-25 03:24 PM, John Chambers wrote:
On 3/24/12 5:43 PM, Paul Gilbert wrote:


On 12-03-24 08:11 PM, John Chambers wrote:


On 3/24/12 1:29 PM, Paul Gilbert wrote:
(I think this is being caused by the new methods package in RC.)
Possibly, but the methods package isn't particularly "new" in its method
selection.

We need to see the definition of the class.

Is there a way to know which class it is that we need to see the
definition for?

It's in the note: 'target signature "TSMySQLConnection#integer"'. In
functional OOP with multiple dispatch, it's all the classes that matter
in general, but in this and most cases, one class is likely the relevant
one: "TSMySQLConnection". That was why I said what I did before.

(We could go to a bit more effort and back-translate the dispatch string
"TSMySQLConnection#integer" into the corresponding formal arguments.
Would be more natural with the INSTALL time tool I mentioned before.
That's the real challenge here -- to give information about this to the
package developer, not the poor user.)

John


Paul

The note implies that it
inherits from both "MySQLConnection" and "dbObjectId", both of which
have methods for coercing to "integer". Hence the ambiguity.

In the RC (March 24) some of my packages are generating a Note

Note: Method with signature "MySQLConnection#integer" chosen for
function "coerce",
target signature "TSMySQLConnection#integer".
"dbObjectId#integer" would also be valid

This is coming from a call to dbGetQuery() in package DBI. The method
with the signature "TSMySQLConnection#integer" is generated
automatically because TSMySQLConnection inherits from
MySQLConnection. (More details below.)

Is there a way to pass this information along to coerce when the
method is generated, or otherwise suppress the Note?
No. Methods are inherited according to rules implied by the class
inheritance; R doesn't allow you to override the inheritance, other than
by being more explicit about the method definition. (It's only a note,
and IMO a relevant one. Be glad the language isn't Dylan, which treats
similar ambiguities as a programming error. :-))

BTW,
1/ It would be nice if the Note mentioned what method is generating
it, in addition to the signature. Debugging for a call several levels
deep in the stack is already hard enough.
?? it does, for coerce() which admittedly you have to know is the method
defined for as(thing, "integer") either directly or indirectly. Unless
you mean showing you the whole method definition, but that seems not
relevant to selection.

If you wanted to see the coerce() method, you need to do
showMethods("coerce"), but I don't think that's relevant. As mentioned,
it's the class hierarchy that matters.

2/ The note only seems to get generated on the first call and then
gets suppressed. This will be nice for users, but makes debugging
harder. Is there a way to prevent suppressing the message?
No. the note is generated when an inherited method is found. That method
is then cached, so the computations required are (fortunately) not
repeated.

It would be nice to have tools that the package writer could apply to
generate all possible inheritance patterns, and flag possible
ambiguities at package INSTALL time, as opposed to when the package is
used. But it's likely that would generate so many cases unlikely to
occur that the package developer would ignore it, even assuming the
developer was energetic enough to use the tool in the first place.
o
3/ It seems strange that getMethod() cannot find the methods even
though showMethods() shows it. (See below.)
I think you're confusing getMethod(), which only finds directly defined
methods, with selectMethod() which replicates the inheritance
computations.

In any case the selection of the method has been specified for you
already.

John

Paul
________

>showMethods("dbGetQuery")
Function: dbGetQuery (package DBI)
conn="MySQLConnection", statement="character"

> z <- TSget("Series 1", con, TSrepresentation="timeSeries")
Note: Method with signature "MySQLConnection#integer" chosen for
function "coerce",
target signature "TSMySQLConnection#integer".
"dbObjectId#integer" would also be valid
Loading required package: zoo

Attaching package: ‘zoo’

The following object(s) are masked from ‘package:timeSeries’:

time<-

The following object(s) are masked from ‘package:base’:

as.Date, as.Date.numeric

> showMethods("dbGetQuery")
Function: dbGetQuery (package DBI)
conn="MySQLConnection", statement="character"
conn="TSMySQLConnection", statement="character"
(inherited from: conn="MySQLConnection", statement="character")

> getMethod("dbGetQuery", signature = c("TSMySQLConnection",
statement="character"))
Error in getMethod("dbGetQuery", signature = c("TSMySQLConnection",
statement = "character")) :
No method found for function "dbGetQuery" and signature
TSMySQLConnection, character
>

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel



______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to