Results change when environment supplied (envir=) to evaluate
I get a different result when executing the code below, depending on whether I supply a new environment. I am using evaluate 0.8 on R 3.2.2.
input <- "print.dog <- function(d) print(\"woof\")\nz = 1:20;\nclass(z) <- \"dog\"\nz";
e <- new.env(parent=globalenv());
evaluate::replay(evaluate::evaluate(input=input, envir=e));
produces
> print.dog <- function(d) print("woof")
> z = 1:20;
> class(z) <- "dog"
> z
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
attr(,"class")
[1] "dog"
but
evaluate::replay(evaluate::evaluate(input=input));
produces
> print.dog <- function(d) print("woof")
> z = 1:20;
> class(z) <- "dog"
> z
[1] "woof"
which I think is correct. Unfortunately for me I would like to replace the environment.
I guess that the print.dog function is being put in e, but that whatever handles the default printing of visible values is not executing in that environment. I have stared at eval.R and I cannot work out what makes visible values print. Any clues?
I think I have found a workaround:
evaluate::replay(eval(quote(evaluate::evaluate(input=input)), envir=e))
No, I fooled myself, the above workaround does not work. The best I can come up with is to modify the code to assign print.dog into the global environment:
input <- "print.dog <<- function(d) print(\"woof\")\nz = 1:20;\nclass(z) <- \"dog\"\nz";
This could be either a bug or feature. If print.dog is intended to be an S3 method, it should be declared in the package namespace (using S3method(generic, class)). Normally it works even if it is not declared since print.dog is created in the global environment by default. S3 is a casual system after all.
I don't see a straightforward fix. If you want to give it a try, you may start from https://github.com/hadley/evaluate/blob/master/R/eval.r#L158-L163 The value_handler is from here: https://github.com/hadley/evaluate/blob/master/R/output.r#L28
Hi @yihui, Thanks, I understand your point. I think in my case that I can work around my problem by using envir=globalenv(). In some respects this is a righteous solution because it more like the real R command line. I have not closed this Issue because perhaps someone else will follow my path, but I do not mind if it is closed.
Okay, I'll wait for one more vote before tackling this problem :)
S3 method registration in the global environment has changed quite a bit in the last ~8 years , so I'm closing this because it's likely no longer relevant.