Skip to content

Workspace Viewer is evaluating active bindings when populating its view #1030

@MilesMcBain

Description

@MilesMcBain

Describe the bug

The workspace viewer is evaluating active bindings in the .Globalenv each time code is run in an R session managed by the VSCode-R extension.

To Reproduce

Here is some code from the help for makeActiveBinding:

f <- local( {
    x <- 1
    function(v) {
       if (missing(v))
           cat("get\n")
       else {
           cat("set\n")
           x <<- v
       }
       x
    }
})
makeActiveBinding("fred", f, .GlobalEnv)
bindingIsActive("fred", .GlobalEnv)

This is the result of evaluating this code in an R session managed by the VSCode-R extension:

> f <- local( {
+     x <- 1
+     function(v) {
+        if (missing(v))
+            cat("get\n")
+        else {
+            cat("set\n")
+            x <<- v
+        }
+        x
+     }
+ })
f, .GlobalEnv)
bindingIsActive("fred", .GlobalEnv)> makeActiveBinding("fred", f, .GlobalEnv)
get
get
get
get
> bindingIsActive("fred", .GlobalEnv)
[1] TRUE
get
get
get
get
> fred
get
[1] 1
get
get
get
get
> "nothing"
[1] "nothing"
get
get
get
get

Do you want to fix by self? (We hope your help!)

Yes / No - If you want to leave it for me, I can fix it, but I may not get to it for some days.

(If yes,) what kind of help do you want? (e.g. Which file should I fix, Survey (related documents)

I can see that part of the issue is in vsc.R here:

is_promise <- rlang::env_binding_are_lazy(env, all_names)
.

rlang::env_binding_are_lazy and rlang::env_binding_are_active both seem to evaluate active bindings twice(!), as confirmed by this test, using the example fred active binding:

> rlang::env_binding_are_lazy(.GlobalEnv, "fred")
get
get
 fred
FALSE
 rlang::env_binding_are_active(.GlobalEnv, "fred")
get
get
fred
TRUE

This does not happen with the base tooling:

bindingIsActive("fred", .GlobalEnv)
[1] TRUE

So the answer is probably to put the active binding check first using the base tooling, and then ensure names associated with these binding are not seen by rlang::env_binding_are_lazy.

PS, this is probably unexpected behavior for rlang::env_binding_are_active. I'll raise this over on rlang.

Expected behavior
Same code in a plain R terminal:

> f <- local( {
+     x <- 1
+     function(v) {
+        if (missing(v))
+            cat("get\n")
+        else {
+            cat("set\n")
+            x <<- v
+        }
+        x
+     }
+ })
> makeActiveBinding("fred", f, .GlobalEnv)
> bindingIsActive("fred", .GlobalEnv)
[1] TRUE
> fred
get
[1] 1

Screenshots
NA

Environment (please complete the following information):

  • OS: Windows
  • VSCode Version: 1.64.2
  • R Version: 4.1.2
  • vscode-R version: 2.4.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions