[Rd] codetools wrongly complains about lazy evaluation in S4 methods

Duncan Murdoch murdoch@dunc@n @end|ng |rom gm@||@com
Mon Jun 12 20:42:32 CEST 2023


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 using 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 using r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>> ______________________________________________
>>> R-devel using r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>
> 
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list