[Rd] methods/namespaces/possible bug

Duncan Murdoch murdoch at stats.uwo.ca
Wed Jul 16 00:49:56 CEST 2008


On 15/07/2008 5:19 PM, Kasper Daniel Hansen wrote:
> On Jul 15, 2008, at 12:00 PM, Duncan Murdoch wrote:
> 
>> On 7/15/2008 2:11 PM, Kasper Daniel Hansen wrote:
>>> Using
>>>> methods("plot")
>>>  [1] plot.Date*          plot.HoltWinters*   plot.POSIXct*
>>>  [4] plot.POSIXlt*       plot.TukeyHSD       plot.acf*
>>>  [7] plot.data.frame*    plot.decomposed.ts* plot.default
>>> [10] plot.dendrogram*    plot.density        plot.ecdf
>>> [13] plot.factor*        plot.formula*       plot.hclust*
>>> [16] plot.histogram*     plot.isoreg*        plot.lm
>>> [19] plot.medpolish*     plot.mlm            plot.ppr*
>>> [22] plot.prcomp*        plot.princomp*      plot.profile.nls*
>>> [25] plot.spec           plot.spec.coherency plot.spec.phase
>>> [28] plot.stepfun        plot.stl*           plot.table*
>>> [31] plot.ts             plot.tskernel*
>>>    Non-visible functions are asterisked
>>> I don't see plot.function listed. As I read the man page for  
>>> methods I  would say that the search is just looking for functions  
>>> with the right  type of name.
>> In a package with a NAMESPACE (like the graphics package, where  
>> plot.function lives), a function needs to be declared to be an  
>> S3method to show up in this list.  plot.function is not declared as  
>> an S3 method.
>>
>> I don't know the reason for this, but I assume it's intentional:   
>> take a look at the plot() generic:  it has special case code to  
>> handle functions.
> 
> Let me just state that if I do
> 
> plot(sin)
> 
> plot.function gets called. This looks to me (as a somewhat experienced  
> R user) as a clear case of method dispatching. I call something that I  
> think most of us think of as a generic, with a function argument and I  
> cannot see that possibility when I do a methods("plot"). This use case  
> is not entirely far out - I have just been teaching and wanted to show  
> how I could see what happened when I called plot on sin and lo and  
> behold, plot.function is not in the list of methods("plot")
> 
> I can see that there is special code in plot for handling dispatching  
> on a function. I can see that is it handled differently (ie. not with  
> a call to UseMethod) but from my point of view, the call
>    plot(sin)
> looks and feels like methods dispatching. I would say plot is a generic.
> 
> Finally the help page for plot.function states
> ## S3 method for class 'function':
>       plot(x, y = 0, to = 1, from = y, xlim = NULL, ...)
> 
> So I think something should be cleaned up here.

I've made attempts in the past to clean this up, and they introduced 
bugs and/or broke traditional behaviour.  See revisions 42827 through 
43202 to src/library/graphics/R/plot.R.  The big problem is that the 
function has traditionally worked in a way that (as far as I know) an S3 
method can't work, but we'd really like to pretend it is one.

Maybe declaring it as an S3method would be fine, but maybe it would have 
weird side effects, since it isn't being called by UseMethod.  Maybe 
changing the man page to state correctly that it's not an S3 method 
would be the best solution, but it acts so much like one that that might 
be misleading.  However, after my last attempt at improvements I'm 
reluctant to touch it again, though I agree it isn't perfect.

Duncan Murdoch

> 
> Kasper
> 
>> So if this is a bug, I think it's a documentation bug in the ? 
>> plot.function man page, where plot.function should be documented to  
>> act a lot like an S3 method, but not identically like one:  notice  
>> the special handling of the y axis label.
>>
>>
>>> If I define a plot.function in my global workspace,  
>>> methods("plot")  picks it up
>>>> plot.function = function() {print("blah")}
>>>> methods("plot")
>>>  [1] plot.Date*          plot.HoltWinters*   plot.POSIXct*
>>>  [4] plot.POSIXlt*       plot.TukeyHSD       plot.acf*
>>>  [7] plot.data.frame*    plot.decomposed.ts* plot.default
>>> [10] plot.dendrogram*    plot.density        plot.ecdf
>>> [13] plot.factor*        plot.formula*       plot.function
>>> [16] plot.hclust*        plot.histogram*     plot.isoreg*
>>> [19] plot.lm             plot.medpolish*     plot.mlm
>>> [22] plot.ppr*           plot.prcomp*        plot.princomp*
>>> [25] plot.profile.nls*   plot.spec           plot.spec.coherency
>>> [28] plot.spec.phase     plot.stepfun        plot.stl*
>>> [31] plot.table*         plot.ts             plot.tskernel*
>>
>> Functions declared in the global workspace are handled by patterns  
>> on the name, since you can't declare things there:  there's no  
>> NAMESPACE file.
>>
>>>    Non-visible functions are asterisked
>>> Based on this, I think that methods("plot") should return   
>>> plot.function, so I am almost ready to take the bug word in my mouth.
>>> When I debug the methods function it gets to the line
>>>   S3reg <- ls(get(".__S3MethodsTable__.", envir = defenv), pattern  
>>> =  name)
>>> where it searches the .__S3MethodsTable__. object. Consulting the  
>>> help  page it seems that this object is part of the namespace  
>>> functionality.
>>> My guess is that something goes wrong because function is a  
>>> reserved  word?
>> I don't think so.
>>
>> Duncan Murdoch
>> 	
>>> Kasper
>>> This has been tested under R-2.7.1 on Mac OS X and under a not too   
>>> recent version of R-devel under x86_64. My sessionInfo for the Mac   
>>> version is
>>>> sessionInfo()
>>> R version 2.7.1 (2008-06-23)
>>> i386-apple-darwin8.10.1
>>> locale:
>>> en_US.UTF-8/en_US.UTF-8/C/C/en_US.UTF-8/en_US.UTF-8
>>> attached base packages:
>>> [1] stats     graphics  grDevices utils     datasets  methods   base
>>> loaded via a namespace (and not attached):
>>> [1] tools_2.7.1
>>> ______________________________________________
>>> R-devel at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list