Attaching a temporary namespace to a search path

This question is similar to the next post , because I am still not completely convinced that in terms of code reliability, it would be far better to do a typification of namespace::foo() instead of just typing foo() and praying to get the desired result ; -)

Actual question

I know this applies pretty much to the “standard R conventions,” but let me say that I'm curious ;-) Can I somehow attach a temporary namespace to the search path?


Motivation

At the moment when my mypkg package is still in a "developmental stage" (i.e. not a real R package yet ):

  • I would like to pass my functions to mypkg environment instead of .GlobalEnv
  • then attach mypkg to the search path (as soon as possible to the true namespace)
  • to be able to call mypkg::foo()

I understand perfectly well that the :: call has its drawbacks (it takes more time than just entering the function name and let R handle the search implicitly) and / or may not be considered necessary because of the way a) R scans the search path and b) packets can import your dependencies (that is, use "Import" instead of "Depends", rather than export certain functions, etc.). But I saw how my code crashed at least twice due to the fact that certain (basic) functions were rewritten in some package, so I switched from "blind trust" to the mode "better to be safe than sorry ; -)

What i tried

AFAIU, namespaces are basically nothing more than some kind of special kind of environment

 > search() [1] ".GlobalEnv" "package:stats" "package:graphics" [4] "package:grDevices" "package:utils" "package:datasets" [7] "package:methods" "Autoloads" "package:base" > asNamespace("base") <environment: namespace:base> 

And there is an attach() function that attaches objects to the search path. So here is what I thought:

 temp.namespace <- new.env(parent=emptyenv()) attach(temp.namespace) > asNamespace("temp.namespace") Error in loadNamespace(name) : there is no package called 'temp.namespace' 

I think I will have to work with attachNamepace() and find out what this expects before it is called in library() . Any ideas?


EDIT

Regarding Hadley's comment: I wouldn’t care if the nested environment is a full namespace or just an ordinary environment if I can extend :: while maintaining the function of syntactic narrowing (i.e. the ability to call pkg::foo() instead "::"(pkg="pkg", name="foo")() ).

Here's what the "::" function looks like:

 > get("::") function (pkg, name) { pkg <- as.character(substitute(pkg)) name <- as.character(substitute(name)) getExportedValue(pkg, name) } 

This is what it should also do if R discovers that pkg is actually not a namespace, but simply an environment tied to a search path:

 "::*" <- function (pkg, name) { pkg <- as.character(substitute(pkg)) name <- as.character(substitute(name)) paths <- search() if (!pkg %in% paths) stop(paste("Invalid namespace environment:", pkg)) pos <- which(paths == pkg) if (length(pos) > 1) stop(paste("Multiple attached envirs:", pkg)) get(x=name, pos=pos) } 

This works, but there is no syntactic sugar:

 > "::*"(pkg="tempspace", name="foo") function(x, y) x + y > "::*"(pkg="tempspace", name="foo")(x=1, y=2) [1] 3 

How can I call pkg::*foo(x=1, y=2) (without considering the fact that ::* is really a bad name for the function ;-))?

+3
source share
1 answer

There is something wrong with your motivation: your namespace should NOT be tied to the search path in order to use the "::" notation, it's actually the other way around.

The search path allows you to select characters by scrolling through all the namespaces associated with the search path.

So, as Hadley told you, you just need to use devtools :: load_all (), that's all ...

0
source

Source: https://habr.com/ru/post/1245204/