[Rd] S4 method implementation for S3 class

Iñaki Úcar i.ucar86 at gmail.com
Fri Sep 22 19:28:05 CEST 2017


2017-09-22 19:04 GMT+02:00 Michael Lawrence <lawrence.michael at gene.com>:
> The %*% function is a primitive. As it says in the documentation under
> ?Methods_Details
>
>      Methods may be defined for most primitives, and corresponding
>      metadata objects will be created to store them. Calls to the
>      primitive still go directly to the C code, which will sometimes
>      check for applicable methods. The definition of “sometimes” is
>      that methods must have been detected for the function in some
>      package loaded in the session and ‘isS4(x)’ is ‘TRUE’ for the
>      first argument (or for the second argument, in the case of binary
>      operators).
>
> But:
>> isS4(x)
> [1] FALSE
>
> I think this behavior is in the interest of performance. It avoids
> adding S4 dispatch overhead to e.g. matrix objects.

I see, thanks for the explanation.

> In general, it's best to define an S4 class when using S4 dispatch,
> but it sounds like you're stuck using some legacy S3 objects. In that
> case, one would normally define an S3 method for `%*%()` that
> delegates to a custom non-primitive generic, perhaps "matmult" in this
> case. But since %*% is not an S3 generic, that's not an option.
>
> It would help to hear more about the context of the problem.

This is a problem that Edzer Pebesma and I are facing in our packages
units and errors respectively (you can find both on CRAN). They are
designed in a similar way: units or errors are attached to numeric
vectors as an attribute of an S3 class, and Ops, Math and Summary are
redefined to cope with such units/errors.

Then Edzer found that the %*% operator silently drops the attributes,
so we were trying, without success, to set a method for our respective
S3 classes to at least show a warning stating that the units/errors
are being dropped.

Ours are perfect use cases for S3 classes, and it would be a pitty if
we have to switch everything to S4 just to show a warning. Clearly
overkilling. Isn't there another way?

Iñaki



More information about the R-devel mailing list