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

Leo Mada |eo@m@d@ @end|ng |rom @yon|c@eu
Sun Apr 28 17:15:06 CEST 2024


Dear Ivan,

Thank you very much for the response.

Indeed, I was skeptical how R interprets class names and I have supposed it a little bit different.

S3 methods are more like overloaded functions; while S4 methods are more like true methods implemented for a class. But this is very approximate (with many exceptions and anomalies); and many programmers are not used to think like this.

The "proj" class could have both overloaded functions (e.g. for aov class, ...), and also new methods like projection of a point on a line, or projection of a point on a plane (which are still projections).

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.

How can I define a real method "proj.line3d"?
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.

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

And maybe it did what I intended. But I need to "register" the overloaded functions somehow differently?

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).


Thank you very much,

Leonard



________________________________
From: Ivan Krylov <ikrylov using disroot.org>
Sent: Saturday, April 27, 2024 10:08 AM
To: Leo Mada <leo.mada using syonic.eu>; r-package-devel using r-project.org <r-package-devel using r-project.org>
Subject: Re: [R-pkg-devel] Extending proj with proj.line3d methods and overloading the methods

27 ������ 2024 �. 00:49:47 GMT+03:00, Leo Mada via R-package-devel <r-package-devel using r-project.org> �����:
>Dear List-Members,
>
>I try to implement a proj.line3d method and to overload this method as follows:
>
>proj.line3d <- function(p, x, y, z, ...)
>  UseMethod("proj.line3d")
>
>proj.line3d.numeric = function(p, x, y, z, ...) {
>  # ...
>}
>
>proj.line3d.matrix = function(p, x, y, z, ...) {
>  # ...
>}

>p = c(1,2,3)
>line = matrix(c(0,5,2,3,1,4), 2)
>proj.line3d(p, line)
>#  Error in UseMethod("proj.line3d") :
>#   no applicable method for 'proj.line3d' applied to an object of class "c('double', 'numeric')"

>methods(proj)
># [1] proj.aov*           proj.aovlist*       proj.default*       proj.line3d
># [5] proj.line3d.matrix  proj.line3d.numeric proj.lm

In your NAMESPACE, you've registered methods for the generic function 'proj', classes 'line3d.matrix' and 'line3d.numeric', but above you are calling a different generic, 'proj.line3d', for which no methods are registered.

For proj.line3d(<numeric>, <matrix>) to work, you'll have to register the methods for the proj.line3d generic. If you need a visible connection to the proj() generic, you can try registering a method on the 'proj' generic, class 'line3d' *and* creating a class 'line3d' that would wrap your vectors and matrices:

proj(line3d(p), line) -> call lands in proj.line3d -> maybe additional dispatch on the remaining classes of 'p'?

This seems to work, but I haven't tested it extensively:

> proj.line3d <- \(x, ...) UseMethod('proj.line3d')
> proj.line3d.numeric <- \(x, ...) { message('proj.line3d.numeric'); x }
> line3d <- \(x) structure(x, class = c('line3d', class(x)))
> proj(line3d(pi))
proj.line3d.numeric
[1] 3.141593
attr(,"class")
[1] "line3d"  "numeric"

--
Best regards,
Ivan

	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list