Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment operator := changes the body of a wrapper function #3890

Closed
kirillmayantsev opened this issue Sep 17, 2019 · 4 comments · Fixed by #3891
Closed

Assignment operator := changes the body of a wrapper function #3890

kirillmayantsev opened this issue Sep 17, 2019 · 4 comments · Fixed by #3891
Milestone

Comments

@kirillmayantsev
Copy link

Hello!

Minimal reproducible example:

library(data.table)

f = function(flag = FALSE) {
  dt1 = data.table(a = 1)
  dt2 = data.table(a = 1)
  dt3 = dt1[, .(a, b = 0)]
  
  print(body(f))
  if (flag) dt3[dt2, b := 999, on = "a"]
  print(body(f))
  
  return(invisible(dt3))
}

f(flag = FALSE)
f(flag = TRUE)

> f(flag = FALSE)
{
    dt1 = data.table(a = 1)
    dt2 = data.table(a = 1)
    dt3 = dt1[, .(a, b = 0)]
    print(body(f))
    if (flag) 
        dt3[dt2, `:=`(b, 999), on = "a"]
    print(body(f))
    return(invisible(dt3))
}
{
    dt1 = data.table(a = 1)
    dt2 = data.table(a = 1)
    dt3 = dt1[, .(a, b = 0)]
    print(body(f))
    if (flag) 
        dt3[dt2, `:=`(b, 999), on = "a"]
    print(body(f))
    return(invisible(dt3))
}

> f(flag = TRUE)
{
    dt1 = data.table(a = 1)
    dt2 = data.table(a = 1)
    dt3 = dt1[, .(a, b = 0)]
    print(body(f))
    if (flag) 
        dt3[dt2, `:=`(b, 999), on = "a"]
    print(body(f))
    return(invisible(dt3))
}
{
    dt1 = data.table(a = 1)
    dt2 = data.table(a = 1)
    dt3 = dt1[, .(a, b = 999)]
    print(body(f))
    if (flag) 
        dt3[dt2, `:=`(b, 999), on = "a"]
    print(body(f))
    return(invisible(dt3))
}

As you can see, after assigning (:=) a new value to column "b" (when flag is TRUE), the body of "f" function is changed on the line "dt3 = ..." ("b = 0" is replaced by "b = 999"). The result of function run will then be different when executing it with FALSE flag value.

Output of sessionInfo():

R version 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7600)

Matrix products: default

locale:
[1] LC_COLLATE=Russian_Russia.1251  LC_CTYPE=Russian_Russia.1251    LC_MONETARY=Russian_Russia.1251
[4] LC_NUMERIC=C                    LC_TIME=Russian_Russia.1251    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] data.table_1.12.3

loaded via a namespace (and not attached):
[1] compiler_3.5.1 tools_3.5.1    yaml_2.2.0
@jangorecki jangorecki added this to the 1.12.4 milestone Sep 17, 2019
@mattdowle
Copy link
Member

Thanks for the great report! I can also reproduce in v1.12.2 too.

@kirillmayantsev
Copy link
Author

@mattdowle , Thanks!

After further investigations it comes out that there is no need for a wrapper-function.
Here is a concise example for this issue:

library(data.table)
value = 0
dt1 = data.table(a = 1)
dt2 = dt1[, .(a, b = ..value)]
dt2[1, b := 999]
print(value)

@mattdowle
Copy link
Member

Thanks. I found the line at fault yesterday and did wonder that it might not be wrapper only. So it's really good to have an example already. WIP ...

@mattdowle
Copy link
Member

Related #3766. Thanks @kirillmayantsev for not giving up on us!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants