[R-pkg-devel] Extending proj with proj.line3d methods and overloading the methods

Ivan Krylov |kry|ov @end|ng |rom d|@root@org
Sun Apr 28 20:15:42 CEST 2024


В Sun, 28 Apr 2024 15:15:06 +0000
Leo Mada <leo.mada using syonic.eu> пишет:

> This is why I intended to define a new method "proj.line3d" and
> overload this method. But it seems that R interprets "line3d.numeric"
> as a class - which originates probably from the "data,frame" class.

It may help to call the original 'proj' function and your new
'proj.line3d' function "generics", because that's what most S3
literature calls these functions that you overload. This separates them
from the "methods" 'proj.line3d.numeric' and 'proj.line3d.matrix' that
can be said to "implement" or "overload" the generic.

A concise but very readable guide to S3 and other built-in OOP systems
in R can be found in Advanced R by Hadley Wickham:
http://adv-r.had.co.nz/OO-essentials.html#s3

> How can I define a real method "proj.line3d"?

In order to export an S3 generic and register methods for it from a
package, you need the following directives in your NAMESPACE:

export(proj.line3d)
S3method(proj.line3d, numeric) # will use function proj.line3d.numeric
S3method(proj.line3d, matrix) # similar

<https://cran.r-project.org/doc/manuals/R-exts.html#Registering-S3-methods>

> There might be some limitations from Roxygen as well (as I use it for
> the package); but it might be easier to proceed, once I understand
> how to do it in R.

The roxygen2 documentation says that if there are multiple dots in the
name of a function, you need to use the two-argument form of the
@method keyword: @method proj.line3d numeric (untested).
<https://roxygen2.r-lib.org/articles/rd-other.html#s3>

> I thought that this solves the problem:
> proj.line3d <- function(p, x, y, z, ...)
>   UseMethod("proj.line3d")

Right. This is the definition of an S3 generic generic in R. As long as
all the methods will also accept arguments (p, x, y, z, <maybe extra
arguments here>, <dots>), all will be fine.

> The other solution, as you pointed out, is more cumbersome; and it
> needs 2 separate classes, so I would need to define "proj" as an S4
> class (as S3 does not handle 2 classes at once).

Moreover, you still need an exported generic proj.line3d and registered
methods for it to work. Inheritance does work in S3 (see NextMethod()),
but it alone won't help you call proj.line3d.numeric() from proj() and
'numeric' x.

-- 
Best regards,
Ivan



More information about the R-package-devel mailing list