Skip to content

[R-pkg-devel] failing S3 dispatch

5 messages · Jens Oehlschlägel, Duncan Murdoch

#
I didn't find an answer elsewhere:

My package 'bit' creates a S3 generic 'clone' and exports it. 
Furthermore it registers a S3 method 'clone.default' (not exported).

My package 'ff' imports package 'bit' and exports and registers a new S3 
method 'clone.ff'. However, calling 'clone(ffobj)' dispatches to 
clone.default instead of clone.ff !? Why?

What is the recommended way to create new S3-methods that get 
dispatched? In earlier versions of the packages I simply exported 
everything - that worked.

Best


Jens


 > require(ff)
 >
 > a <- as.ff(0:9)
 > class(x)
[1] "ff_vector" "ff"
 >
 > x <- clone(a)
 > y <- bit:::clone.default(a)
 > z <- clone.ff(a)
 >
 > # cloned ffobjects should have different filenames>

 > filename(a)? # original
[1] "/tmp/Rtmpk17JRZ/ff/clone1ed54cbb5060.ff"
 >
 > filename(x)? # unexpected equal (dispatch to clone.default)
[1] "/tmp/Rtmpk17JRZ/ff/clone1ed54cbb5060.ff"
 >
 > filename(y)? # expected equal
[1] "/tmp/Rtmpk17JRZ/ff/clone1ed54cbb5060.ff"
 >
 > filename(z)? # OK
[1] "/tmp/Rtmpk17JRZ/ff/clone1ed551d3ee66.ff"

 > version
 ?????????????? _
platform?????? x86_64-pc-linux-gnu
arch?????????? x86_64
os???????????? linux-gnu
system???????? x86_64, linux-gnu
status
major????????? 4
minor????????? 1.1
year?????????? 2021
month????????? 08
day??????????? 10
svn rev??????? 80725
language?????? R
version.string R version 4.1.1 (2021-08-10)
nickname?????? Kick Things
#
On 19/10/2021 3:43 p.m., Jens Oehlschl?gel wrote:
You should show us the NAMESPACE entries involving clone and clone.ff 
from ff.

Some comments that may or may not be relevant:

  - Normally you wouldn't export clone.ff, it's enough to register it 
using S3method().

  - You may have created a new generic named clone, and that's what 
clone.ff would attach itself to.  You can have bit::clone and ff::clone 
as different generics and that would cause problems.
I import the generic and use S3method(generic, method).  I don't export 
the methods, so I wouldn't be able to call z <- clone.ff(a).

Duncan Murdoch
#
Thank you Duncan,

bit NAMESPACE has

S3method(clone,default)
export(clone)

ff NAMESPACE has

import(bit)
# wish of CRAN maintainers: export another time here (now maintained and 
exported in bit)
# without this R CMD CHECK complained, but with it R CMD CHECK complains 
also, how to export again and why?
# clone
#,clone.default
 ?clone.ff
,clone.ffdf
S3method("clone",ff)
S3method(clone, ffdf)
# wish of CRAN maintainers: export another time here (now maintained and 
exported in bit)
#S3method(clone, default)

Best

Jens
On 20.10.21 11:02, Duncan Murdoch wrote:
1 day later
#
Thanks Duncan,

I finally found the reason for the mysterious dispatch-failure: I had an 
unwanted and unexported replicated definition of the 'clone' generic in 
ff's namespace (a left-over).

I still don't understand how this prevented the proper dispatch since 
the duplicate in ff's namespace it was *not* called. I further 
experimented and *any* non-exported object matching the name of the 
generic caused the problem. Scary, maybe worth a check!

Anyhow, removing the non-exported object solved the problem.

Best regards

Jens
On 20.10.21 13:43, Jens Oehlschl?gel wrote:
#
On 21/10/2021 1:23 p.m., Jens Oehlschl?gel wrote:
Your NAMESPACE file contains

   S3method("clone",ff)

When R installs your package, it has to figure out where "clone" lives. 
  You imported a copy of it from bit, and then overwrote that imported 
copy with the replicated definition.

That created a new generic belonging to ff, and that's the one that your 
clone.ff method was attached to.

When you called clone(x), you called the bit::clone generic which never 
received the registration, so dispatch to clone.ff never happened.

It makes sense:  you don't want a generic in one package to interfere 
with an unrelated generic in another package that happens to have the 
same name.

Duncan Murdoch