[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