Why does lintr say "warning: no visible binding for global variable ‘Cloaked’"?

2.9k Views Asked by At

I'm sure that this is a misunderstanding of mine, since I'm not really an R programmer...

I have my code here: https://gist.github.com/bnsh/3839c4eb2c6b31e32c39ec312014b2b8

#! /usr/bin/env Rscript

library(R6)

Cloaked <- R6::R6Class("Cloaked",
  public = list(
    msg = function() {
      return(paste(
        "this code _works_, but lintr (https://github.com/jimhester/lintr)",
        "complains that cloak_class.R:19:8: warning: no visible binding for",
        "global variable ‘Cloaked’ when I try to use Cloaked within a",
        "function. It's fine tho, if I use it _outside_ a function."
      ))
    }
  )
)

main <- function() {
  c <- Cloaked$new()
  c$msg()
}

main()

It works... But, lintr complains: "cloak_class.R:19:8: warning: no visible binding for global variable ‘Cloaked’"

Actually, it's not about a class, really, because this also complains:

#! /usr/bin/env Rscript

cloaked <- function() {
  return(paste(
    "this code _works_, but lintr (https://github.com/jimhester/lintr)",
    "complains that cloak_function.R:13:3: warning: no visible global",
    "function definition for ‘cloaked’ when I try to use cloaked within",
    "a function. It's fine tho, if I use it _outside_ a function."
  ))
}

main <- function() {
  cloaked()
}

main()

This code also runs, but lintr says: cloak_function.R:13:3: warning: no visible global function definition for ‘cloaked’

Why? Short of doing something blunt instrument like # nolint start/# nolint end, what can I do to satisfy lintr?

Thanks!

2

There are 2 best solutions below

0
On

I've just started with lintr and had the same problem. It appears to be a bug.

https://github.com/REditorSupport/atom-ide-r/issues/7 and the actual issue https://github.com/jimhester/lintr/issues/27

The only workaround for now (short of fixing the bug within lintr) is to disable the object linter (which is not all that ideal as it will not catch genuine errors of this form). e.g.

with_defaults(object_usage_linter=NULL)

(I don't think the object usage linter is intended for scripts but rather packages - as far as I can tell, to work it will eval the entire script (!) to see what globals are defined. For a package where the R files are all function definitions that's fine, but for a script you don't really want to run the whole script every time you lint the file)

0
On

Using the linters argument in the lintr functions:

lint("myfile.R", linters = linters_with_defaults(
  object_length_linter = NULL,
  object_name_linter = NULL,
  object_usage_linter = NULL))

Or use a .lintr file in the project folder (working directory)

linters: linters_with_defaults(
    line_length_linter(140), 
    commented_code_linter = NULL,
    object_name_linter = NULL,
    object_usage_linter = NULL,
    brace_linter = NULL,
    object_length_linter = NULL
  )