Re: [Rd] codetools wrongly complains about lazy evaluation in S4 methods
Most of the errors, warnings and notes generated by R CMD check are generated by code in the tools package, usually in the tools/R/QC.R source file. Search that file for the error message, then backtrack to find the code that causes it to be triggered. If I recall correctly, it works on the evaluated source rather than the actual source, so it will only see the result of evaluating `setMethod` in your example. I don't know the methods package well enough to know exactly what that does, but presumably it produces a function and hides it somewhere so that the S4 dispatch can find it when it needs to. Duncan Murdoch On 12/06/2023 2:03 p.m., Mikael Jagan wrote: Thanks both. Yes, I was aware of globalVariables, etc. I guess I was hoping to be pointed to the right place in the source code, in case the issue could be addressed properly, notably as it seems to have already been addressed for functions that are not S4 methods, i.e., codetools is apparently not bothered by def <- function(x = y) { y <- 0; x } but still complains about setMethod("someGeneric", "someClass", def) ... Mikael On 2023-06-07 5:13 am, Gabriel Becker wrote: The API supported workaround is to call globalVariables, which, essentially, declares the variables without defining them (a distinction R does not usually make). The issue with this approach, of course, is that its a very blunt instrument. It will cause false negatives if you accidentally use the same symbol in a standard evaluation context elsewhere in your code. Nonetheless, that's the intended approach as far as i know. Best, ~G On Wed, Jun 7, 2023 at 1:07 AM Serguei Sokol via R-devel < r-devel@r-project.org> wrote: Le 03/06/2023 à 17:50, Mikael Jagan a écrit : In a package, I define a method for not-yet-generic function 'qr.X' like so: > setOldClass("qr") > setMethod("qr.X", signature(qr = "qr"), function(qr, complete, ncol) NULL) The formals of the newly generic 'qr.X' are inherited from the non-generic function in the base namespace. Notably, the inherited default value of formal argument 'ncol' relies on lazy evaluation: > formals(qr.X)[["ncol"]] if (complete) nrow(R) else min(dim(R)) where 'R' must be defined in the body of any method that might evaluate 'ncol'. To my surprise, tools:::.check_code_usage_in_package() complains about the undefined symbol: qr.X: no visible binding for global variable 'R' qr.X,qr: no visible binding for global variable 'R' Undefined global functions or variables: R I think this issue is similar to the complaints about non defined variables in expressions involving non standard evaluation, e.g. column names in a data frame which are used as unquoted symbols. One of workarounds is simply to declare them somewhere in your code. In your case, it could be something as simple as: R=NULL Best, Serguei. I claim that it should _not_ complain, given that lazy evaluation is a really a feature of the language _and_ given that it already does not complain about the formals of functions that are not S4 methods. Having said that, it is not obvious to me what in codetools would need to change here. Any ideas? I've attached a script that creates and installs a test package and reproduces the check output by calling tools:::.check_code_usage_in_package(). Hope it gets through. Mikael __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Rd macros are not expanded inside of \eqn{} or \deqn{}
A description of the format is given in this document: https://developer.r-project.org/parseRd.pdf As far as I know that document is still up to date. As it says in Table 3, \eqn and \deqn take "Verbatim" arguments. That mode is described in the introduction to Section 2; it contains text and comments, so by design no macros are expanded. I think it's unlikely that this would change. The problem is that the equation markup can contain LaTeX macros. So the parser would have to have a new mode where it distinguished between LaTeX macros and Rd macros. But then how would you write true verbatim text, where you're trying to discuss the macros? It gets complicated very quickly. What you could conceivably do is write your own macro that passed its content to R code that expanded your user-defined macros. It sounds complicated, and would probably be hard to get right. Duncan Murdoch On 12/06/2023 1:55 p.m., Mikael Jagan wrote: I was a bit surprised to learn that, if one has an Rd file as below: %% zzz.Rd \newcommand{\zzz}{whatever} \name{zzz} \title{zzz} \description{ \zzz{} \eqn{\zzz{}} \deqn{\zzz{}} } then the macro is _not_ expanded inside of \eqn{} or \deqn{} when parsed to text or HTML. Is this behaviour intentional? Could it be changed? Inside of \eqn{} and \deqn{} is where I am _most_ likely to want to use macros, at least since R 4.2.0, which added KaTeX support ... See output pasted below. Mikael > tools::Rd2txt(tools::parse_Rd("zzz.Rd")) zzz Description: whatever \zzz{} \zzz{} > tools::Rd2HTML(tools::parse_Rd("zzz.Rd")) R: zzz https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.css";> const macros = { "\\R": "\\textsf{R}", "\\code": "\\texttt"}; function processMathHTML() { var l = document.getElementsByClassName('reqn'); for (let e of l) { katex.render(e.textContent, e, { throwOnError: false, macros }); } return; } https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.js"; onload="processMathHTML();"> zzzR Documentation zzz Description whatever \zzz{} \zzz{} __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] codetools wrongly complains about lazy evaluation in S4 methods
Thanks both. Yes, I was aware of globalVariables, etc. I guess I was hoping to be pointed to the right place in the source code, in case the issue could be addressed properly, notably as it seems to have already been addressed for functions that are not S4 methods, i.e., codetools is apparently not bothered by def <- function(x = y) { y <- 0; x } but still complains about setMethod("someGeneric", "someClass", def) ... Mikael On 2023-06-07 5:13 am, Gabriel Becker wrote: The API supported workaround is to call globalVariables, which, essentially, declares the variables without defining them (a distinction R does not usually make). The issue with this approach, of course, is that its a very blunt instrument. It will cause false negatives if you accidentally use the same symbol in a standard evaluation context elsewhere in your code. Nonetheless, that's the intended approach as far as i know. Best, ~G On Wed, Jun 7, 2023 at 1:07 AM Serguei Sokol via R-devel < r-devel@r-project.org> wrote: Le 03/06/2023 à 17:50, Mikael Jagan a écrit : In a package, I define a method for not-yet-generic function 'qr.X' like so: > setOldClass("qr") > setMethod("qr.X", signature(qr = "qr"), function(qr, complete, ncol) NULL) The formals of the newly generic 'qr.X' are inherited from the non-generic function in the base namespace. Notably, the inherited default value of formal argument 'ncol' relies on lazy evaluation: > formals(qr.X)[["ncol"]] if (complete) nrow(R) else min(dim(R)) where 'R' must be defined in the body of any method that might evaluate 'ncol'. To my surprise, tools:::.check_code_usage_in_package() complains about the undefined symbol: qr.X: no visible binding for global variable 'R' qr.X,qr: no visible binding for global variable 'R' Undefined global functions or variables: R I think this issue is similar to the complaints about non defined variables in expressions involving non standard evaluation, e.g. column names in a data frame which are used as unquoted symbols. One of workarounds is simply to declare them somewhere in your code. In your case, it could be something as simple as: R=NULL Best, Serguei. I claim that it should _not_ complain, given that lazy evaluation is a really a feature of the language _and_ given that it already does not complain about the formals of functions that are not S4 methods. Having said that, it is not obvious to me what in codetools would need to change here. Any ideas? I've attached a script that creates and installs a test package and reproduces the check output by calling tools:::.check_code_usage_in_package(). Hope it gets through. Mikael __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Rd macros are not expanded inside of \eqn{} or \deqn{}
I was a bit surprised to learn that, if one has an Rd file as below: %% zzz.Rd \newcommand{\zzz}{whatever} \name{zzz} \title{zzz} \description{ \zzz{} \eqn{\zzz{}} \deqn{\zzz{}} } then the macro is _not_ expanded inside of \eqn{} or \deqn{} when parsed to text or HTML. Is this behaviour intentional? Could it be changed? Inside of \eqn{} and \deqn{} is where I am _most_ likely to want to use macros, at least since R 4.2.0, which added KaTeX support ... See output pasted below. Mikael > tools::Rd2txt(tools::parse_Rd("zzz.Rd")) zzz Description: whatever \zzz{} \zzz{} > tools::Rd2HTML(tools::parse_Rd("zzz.Rd")) R: zzz href="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.css";> const macros = { "\\R": "\\textsf{R}", "\\code": "\\texttt"}; function processMathHTML() { var l = document.getElementsByClassName('reqn');for (let e of l) { katex.render(e.textContent, e, { throwOnError: false, macros }); }return; } https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.js"; onload="processMathHTML();"> zzzR Documentation zzz Description whatever \zzz{} \zzz{} __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel