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

Functions with envir = parent.frame() #38

Closed
krlmlr opened this issue Sep 6, 2014 · 7 comments
Closed

Functions with envir = parent.frame() #38

krlmlr opened this issue Sep 6, 2014 · 7 comments

Comments

@krlmlr
Copy link
Member

krlmlr commented Sep 6, 2014

Compare the following two statements:

"file.rda" %>% load
load("file.rda")

The former will load the data into a temporary environment; the reason is that load is declared as

load <- function (file, envir = parent.frame(), verbose = FALSE)

The same happens with assign and get.

This is at least unexpected, I'm not sure if we should call it a bug. Worse, I'm not sure if this issue can be solved at all in a robust way.

Similar to #32.

@krlmlr krlmlr mentioned this issue Oct 7, 2014
@byzheng
Copy link

byzheng commented Nov 21, 2014

I have the same problem. For my digging, function "pipe" do evaluate "load" and load all variables into the new environment, but this code below returns result with visible = FALSE (L43 in pipe.R).

result <- withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))

So pipe returns results with invisible (L53 in pipe.R)

invisible(result[["value"]])

Not sure how to fix it.

@smbache
Copy link
Member

smbache commented Nov 21, 2014

This is one of those things that keep popping up; on the one hand I am not a fan of side-effect functions like e.g. load, and typically I wrap it in a function which returns whatever is loaded; in general depending "too much" on the environments around is not really good practice. That being said, I know it would be nice to solve this, but to be honest, I am not sure there is an easy fix for it. I'll keep it in mind though...

@byzheng
Copy link

byzheng commented Nov 21, 2014

Thanks for your reply. Andri and Richard Scriven at Stackoverflow provided a solution and explanation:
http://stackoverflow.com/questions/27053935

@hadley
Copy link
Member

hadley commented Nov 21, 2014

Generally, I think it's better to use saveRDS()/writeRDS rather than save()/load() because of how they mess around with environments.

@krlmlr
Copy link
Member Author

krlmlr commented Nov 21, 2014

This issue affects all functions with the construct envir = parent.frame(). ???envir lists more than 800 entries.

Compare (from an interactive prompt):

> parent.frame()
<environment: R_GlobalEnv>
> 1 %>% parent.frame
<environment: 0x4157240>

How about something like the following:

pipe.frame <- function() parent.frame(7)
"b" %>% assign(3, envir = pipe.frame())
b
## [1] 3

The 7 is an implementation detail, consistency could be assured with a unit test. (The example is just a placeholder for any usage of parent.frame in a function call.

I have looked, but haven't found a way to make parent.frame() return the "correct" value from within a pipe.

@hadley
Copy link
Member

hadley commented Jul 2, 2018

I think the best we can do is to provide a convenient way to get the right environment, i.e. #171.

I'm now almost certain that that's no way to implement the pipe that would preserve parent.frame(), without sacrificing properties that we care about more.

@iagogv3
Copy link

iagogv3 commented Oct 14, 2019

I've just found another problem with the save function, which is envir = parent.frame() too, which seems to be related to this issue.

If I save a data frame with pipe:

library(magrittr)
mtcars %>% save(file = "test.rdata")

And later, when I don't have it in the Global Env, I try to load with

load("test.rdata")

it does not load anything. If I save it without pipe, all works as usual.

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

No branches or pull requests

5 participants