If anyone wants to try my demo, they can install the test package using

  remotes::install_github("dmurdoch/testpkg")

and see the demonstration by running

  library(testpkg)
  example(f)

Duncan Murdoch

On 08/05/2023 7:23 p.m., Duncan Murdoch wrote:
On 08/05/2023 6:58 p.m., Simon Urbanek wrote:


On 8/05/2023, at 11:58 PM, Duncan Murdoch <murdoch.dun...@gmail.com> wrote:

There really isn't such a thing as "a function that looks like an S3 method, but 
isn't".  If it looks like an S3 method, then in the proper circumstances, it will be 
called as one.



I disagree - that was the case in old versions, but not anymore. The whole 
point of introducing namespaces and method registration was to make it clear 
when a function is a method and when it is a function. If you export a function 
it won't be treated as a method:

In a package NAMESPACE:
export(foo.cls)
package R code: foo.cls <- function(x) "foo.cls"

in R:
cls=structure(1,class="cls")
foo=function(x) UseMethod("foo")
foo(cls)
Error in UseMethod("foo") :
    no applicable method for 'foo' applied to an object of class "cls"
foo.cls(cls)
[1] "foo.cls"

So R knows very well what is a method and what is a function. If you wanted it 
to be a method, you have to use S3method(foo, cls) and that **is** different 
from export(foo.cls) - quite deliberately so.

That is true for package users, but it's not true within the package.  I
just tested this code in a package:

    levels.no <- function(xx, ...) {
      stop("not a method")
    }

    f <- function() {
      x <- structure(1, class = "no")
      levels(x)
    }

Both levels.no and f were exported.  If I attach the package and call
f(), I get the error

    > library(testpkg)
    > f()
    Error in levels.no(x) : not a method

because levels.no is being treated as a method when levels() is called
in the package.

If I create an x like that outside of the package and call levels(x)
there, I get NULL, because levels.no is not being treated as a method in
that context.

As far as I know, there is no possible way to have a function in a
package that is called "levels.no" and not being treated as a method
within the package.  I don't think there's any way to declare "this is
not a method", other than naming it differently.

Duncan


Cheers,
Simon


In your case the function name is levels.no, and it isn't exported.  So if you happen to 
have an object with a class inheriting from "no", and you call levels() on it, 
levels.no might be called.

This will only affect users of your package indirectly.  If they have objects inheriting 
from "no" and call levels() on them, levels.no will not be called.  But if they 
pass such an object to one of your package functions, and that function calls levels() on 
it, they could end up calling levels.no().  It all depends on what other classes that 
object inherits from.

You can test this yourself.  Set debugging on any one of your functions, then 
call it in the normal way.  Then while still in the debugger set debugging on 
levels.no, and create an object using

   x <- structure(1, class = "no")

and call levels(x).  You should break to the code of levels.no.

That is why the WRE manual says "First, a caveat: a function named gen.cl will be 
invoked by the generic gen for class cl, so do not name functions in this style unless 
they are intended to be methods."

So probably the best solution (even if inconvenient) is to rename levels.no to 
something that doesn't look like an S3 method.

Duncan Murdoch

On 08/05/2023 5:50 a.m., Ulrike Groemping wrote:
Thank your for the solution attempt. However, using the keyword internal
does not solve the problem, the note is still there. Any other proposals
for properly documenting a function that looks like an S3 method, but isn't?
Best, Ulrike
Am 05.05.2023 um 12:56 schrieb Iris Simmons:
You can add

\keyword{internal}

to the Rd file. Your documentation won't show up the in the pdf
manual, it won't show up in the package index, but you'll still be
able to access the doc page with ?levels.no <http://levels.no> or
help("levels.no <http://levels.no>").

This is usually used in a package's deprecated and defunct doc pages,
but you can use it anywhere.

On Fri, May 5, 2023, 06:49 Ulrike Groemping
<ulrike.groemp...@bht-berlin.de> wrote:

      Dear package developeRs,

      I am working on fixing some notes regarding package DoE.base.
      One note refers to the function levels.no <http://levels.no> and
      complains that the
      function is not documented as a method for the generic function
      levels.
      Actually, it is not a method for the generic levels, but a standalone
      internal function that I like to have documented.

      Is there a way to document the function without renaming it and
      without
      triggering a note about method documentation?

      Best, Ulrike

      --
      ##############################################
      ## Prof. Ulrike Groemping
      ## FB II
      ## Berliner Hochschule für Technik (BHT)
      ##############################################
      ## prof.bht-berlin.de/groemping <http://prof.bht-berlin.de/groemping>
      ## Phone: +49(0)30 4504 5127
      ## Fax:   +49(0)30 4504 66 5127
      ## Home office: +49(0)30 394 04 863
      ##############################################

      ______________________________________________
      R-package-devel@r-project.org mailing list
      https://stat.ethz.ch/mailman/listinfo/r-package-devel

______________________________________________
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel

______________________________________________
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel




______________________________________________
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel

Reply via email to