From mtmorgan at fhcrc.org  Tue May 19 05:59:52 2009
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Mon, 18 May 2009 20:59:52 -0700
Subject: [Rd] S4 method dispatch and namespaces: why is default method
 selected
In-Reply-To: <e1fa237d0905180631h5a6144ao5cf5c65b22bb9fce@mail.gmail.com> 
	=?utf-8?q?=28Micha=C5=82?= Bojanowski's message of "Mon,
	18 May 2009 15:31:40 +0200")
References: <e1fa237d0905180631h5a6144ao5cf5c65b22bb9fce@mail.gmail.com>
Message-ID: <6phr5ylagjr.fsf@gopher4.fhcrc.org>

Hi Micha? --

Micha? Bojanowski <michal2992 at gmail.com> writes:

> Hi,
>
> I ran into the following peculiarity involving S4 method dispatch and
> namespaces.
>
> I develop a package which have a namespace and which depends on 'pixmap'
> package, which itself does not have a namespace.
>
> Now, in my package I have a class which has a slot for objects from
> class "pixmap" and I
> want to have a "plot" method for this new class. Not to clutter the point with
> my original code here is a stylized example:
>
>
> # library(pixmap) # so that the class pixmap is available
>
> # class
> setClass("myclass", representation(img="pixmap", title="character",
> other="numeric"))
>
> # method to plot
> setMethod("plot", signature(x="myclass", y="missing"),
> function(x, main=x at title, ...)
> {
>     # plot using the method from pixmap package
>     plot(x=x at img, ...)
>     title(main=main)
>     points(seq(along=x at other), other)
> } )
>
>
> Now, if you try to do this:
>
> library(pixmap)
> f <- system.file(file.path("pictures", "logo.ppm"), package="pixmap")
> o <- new("myclass", img=read.pnm(f), title="some title", other=Inf)
> o
>
> # now this works as the plot method for signature x="pixmap" y="ANY" is
> # dispatched correctly
> plot(o)
>
>
>
> However, when I put all these in a package with Depends field in
> DESCRIPTION having: methods, pixmap, and with the following namespace:
>
>
> importFrom("graphics", "plot")
> exportClasses("myclass")
> exportMethods("plot")
>
>
> things stop working (this is from package test):
>
>
>> f <- system.file(file.path("pictures", "logo.ppm"), package="pixmap")
>> o <- new("myclass", a=read.pnm(f), title="tytul")
>> plot(o)
> Error in as.double(y) :
>   cannot coerce type 'S4' to vector of type 'double'
> Calls: plot ... plot -> .local -> plot -> plot.default -> xy.coords
> Execution halted
>
>
>
> So apparently calling 'plot' dispatches the default method instead of using the
> one from package 'pixmap'. Why?

Not speaking authoritatively, but plot,myclass,missing-method is
defined in your name space, and so has access only to symbols defined
or imported into the name space. The plot,pixmap,ANY-method is not in
your name space (even though it's on the search path), and so is not
found. Clever of the methods package to keep track of this. I think
the only solution is

  pixmap::plot(x=x at img, ...)

Martin

> As far as I understand the documentation and section 10.6 of "Software for Data
> Analysis" the default method should never be selected as far as there are other
> candidates. And there seems to be other candidates, and they seem to be properly
> selected if checked using 'selectMethod' (this is from results from
> package tests):
>
>
>
>
>> showMethods("plot")
> Function: plot (package graphics)
> x="ANY", y="ANY"
> x="myclass", y="missing"
> x="pixmap", y="ANY"
>
>
>> selectMethod("plot", signature(x="pixmap", y="missing"))
> Method Definition:
>
> function (x, y, ...)
> {
>     .local <- function (x, y, xlab = "", ylab = "", axes = FALSE,
>         asp = 1, ...)
>     {
>         x = as(x, "pixmapIndexed")
>         X <- seq(x at bbox[1], x at bbox[3], by = x at cellres[1])
>         Y <- seq(x at bbox[2], x at bbox[4], by = x at cellres[2])
>         image(x = X, y = Y, z = t(x at index[nrow(x at index):1, ,
>             drop = FALSE]), col = x at col, xlab = xlab, ylab = ylab,
>             axes = axes, asp = asp, ...)
>     }
>     .local(x, y, ...)
> }
> <environment: 0x01844e60>
>
> Signatures:
>         x        y
> target  "pixmap" "missing"
> defined "pixmap" "ANY"
>
>
>
>
>
>> sessionInfo()
> R version 2.9.0 (2009-04-17)
> i386-pc-mingw32
>
> locale:
> LC_COLLATE=Polish_Poland.1250;LC_CTYPE=Polish_Poland.1250;LC_MONETARY=Polish_Poland.1250;LC_NUMERIC=C;LC_TIME=Polish_Poland.1250
>
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
>
> other attached packages:
> [1] pixmap_0.4-9
>
> loaded via a namespace (and not attached):
> [1] tools_2.9.0
>
>
>
>
> Thanks in advance!
>
> Best,
> Micha?
>
>
>
> _________________________
> Michal Bojanowski
> http://bojan.3e.pl/weblog
> http://www.fss.uu.nl/soc/bojanowski
> http://www.ifispan.waw.pl/socnierowno
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Martin Morgan
Computational Biology / Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N.
PO Box 19024 Seattle, WA 98109

Location: Arnold Building M1 B861
Phone: (206) 667-2793



[Rd] S4 method dispatch and namespaces: why is default method selected
Martin Morgan