[Rd] Is it a good idea or even possible to redefine attach?
Grant Rettke
gcr at wisdomandwonder.com
Tue Aug 5 23:37:03 CEST 2014
That is delightful.
When I run it like this:
• Start R
• Nothing in .Rprofile
• Paste in your code
╭────
│ gcrenv <- new.env()
│ gcrenv$attach.old <- attach
│ gcrenv$attach <- function(...){stop("NEVER USE ATTACH")}
│ base::attach(gcrenv, name="gcr", warn.conflicts = FALSE)
╰────
• I get exactly what is expected, I think
╭────
│ search()
╰────
╭────
│ [1] ".GlobalEnv" "gcr" "ESSR"
│ [4] "package:stats" "package:graphics" "package:grDevices"
│ [7] "package:utils" "package:datasets" "package:methods"
│ [10] "Autoloads" "package:base"
╰────
Just to be sure:
• Is that what is expected?
• I am surprised because I thought that `gcr' would come first before
`.GlobalEnv'
• Perhaps I mis understand, as `.GlobalEnv' is actually the "REPL"?
My goal is to move that to my .Rprofile so that it is "always run" and I
can forget about it more or less.
Reading [this] I felt like `.First' would be the right place to put it,
but then read further to find that packages are only loaded /after/
`.First' has completed. Curious, I tried it just to be sure. I am now
:).
This is the .Rprofile file:
╭────
│ cat(".Rprofile: Setting CMU repository\n")
│ r = getOption("repos")
│ r["CRAN"] = "http://lib.stat.cmu.edu/R/CRAN/"
│ options(repos = r)
│ rm(r)
│
│ .First <- function() {
│ «same code as above»
│ }
╰────
(I included the repository load, and understand it should not impact
things here)
This is run after normal startup of R:
╭────
│ search()
╰────
╭────
│ [1] ".GlobalEnv" "package:stats" "package:graphics"
│ [4] "package:grDevices" "package:utils" "package:datasets"
│ [7] "gcr" "package:methods" "Autoloads"
│ [10] "package:base"
╰────
When I read this, I read it as:
• My rebind of `attach' occurs
• Then all of the packages are loaded and they are referring to
my-rebound `attach'
• That is a problem because it *will* break package code
• Clearly me putting that code in `.Rprofile' is the wrong place.
What I am looking for now is the "right way" to achieve what is
demonstarted but automatically via a startup file.
My ideas:
• Manually paste the step each time
• Always use Emacs and ESS to run R and add a hook so that the code will
be run after ESS loads
• Something I am missing
[this]
http://stat.ethz.ch/R-manual/R-devel/library/base/html/Startup.html
Grant Rettke | ACM, ASA, FSF, IEEE, SIAM
gcr at wisdomandwonder.com | http://www.wisdomandwonder.com/
“Wisdom begins in wonder.” --Socrates
((λ (x) (x x)) (λ (x) (x x)))
“Life has become immeasurably better since I have been forced to stop
taking it seriously.” --Thompson
On Tue, Aug 5, 2014 at 2:47 PM, Winston Chang <winstonchang1 at gmail.com> wrote:
> On Tue, Aug 5, 2014 at 1:49 PM, Grant Rettke <gcr at wisdomandwonder.com> wrote:
>>
>> Hi,
>>
>> Today I got curious about whether or not I /could/ remove `attach' from
>> my system so:
>> - Backed it up
>> - Implemented a new one
>> - Like this
>>
>> ,----
>> | attach.old <<- attach
>> | attach <<- function(...) {stop("NEVER USE ATTACH")}
>> `----
>>
>> I got the error:
>>
>> ,----
>> | Error: cannot change value of locked binding for 'attach'
>> `----
>>
>> If I unlock `attach' I assume that I could stomp on it... however is
>> that even a good idea?
>>
>> What will I break?
>
>
> If you change the base package environment's copy of `attach` (via
> `as.environment('package:base')`) , probably not much will break,
> except for your own code. If, on the other hand, you change the base
> namespace's copy of `attach` (via `asNamespace('base')`, any package
> that's subsequently loaded and uses `attach` would run into problems.
> Still, either way is probably not a good idea.
>
> I agree with Ista: assigning it yourself in the the global environment
> is a better idea. If you want to keep your global env clear of stuff
> like this, you can put it in an environment and attach that
> environment as a parent of global:
>
> e <- new.env()
> e$attach <- function(...) {stop("NEVER USE ATTACH")}
> base::attach(e, name = "my_stuff", warn.conflicts = FALSE)
>
> # Test it out:
> attach()
>
> # You can see that the "my_stuff" env is the parent of global env
> search()
>
>
> -Winston
More information about the R-devel
mailing list