簡體   English   中英

將臨時命名空間附加到搜索路徑

[英]Attaching a temporary namespace to the search path

這個問題是對這篇文章的后續跟進,因為我仍然不完全相信,就代碼健壯性而言,輸入namespace::foo()習慣而不僅僅是鍵入foo()並不是更好foo()和祈禱你得到期望的結果;-)

實際問題

我知道這嚴重違反了“標准R約定”,但我們只是說我很好奇;-) 是否有可能以某種方式將臨時命名空間附加到搜索路徑?


動機

在我的包mypkg仍然處於“ 開發階段 ”(即不是真正的R包 )的時候:

  • 我想將我的函數源化為環境mypkg而不是.GlobalEnv
  • 然后將mypkg附加到搜索路徑(如果可能的話,作為真正的命名空間)
  • 為了能夠調用mypkg::foo()

我完全清楚調用::有它的缺點(它只需要輸入一個函數的名稱並讓R隱式處理查找所需的時間更長)和/或由於a) R掃描搜索路徑的方式可能不被認為是必要的和b)包可以導入它們的依賴項(即使用“Imports”而不是“Depends”,而不是導出某些函數等)。 但是我已經看到我的代碼至少崩潰了兩次,因為某些軟件包已經覆蓋了某些(基本)函數,所以我從“盲目信任”轉變為“更好的安全而不是抱歉”模式; - )

我嘗試了什么

AFAIU,命名空間原則上只是一些特殊的環境

> 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>

還有attach()函數將對象附加到搜索路徑。 所以這就是我的想法:

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

我想我不得不使用attachNamepace()並在library()調用它之前弄清楚它的期望。 有任何想法嗎?


編輯

關於Hadley的評論:我實際上並不關心附加環境是一個完全成熟的命名空間還是只是一個普通的環境,只要我可以擴展:: 同時保持“語法sugering”功能 (即能夠調用pkg::foo()而不是"::"(pkg="pkg", name="foo")() )。

這就是函數"::"樣子:

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

如果R檢測到pkg實際上不是命名空間而只是鏈接到搜索路徑的某個環境,那么它也應該能夠做到這一點:

"::*" <- 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)
}

它有效,但沒有語法含糖:

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

我怎么能調用pkg::*foo(x=1, y=2) (忽略了::*是一個非常糟糕的函數名稱的事實;-))?

你的動機有些不對勁:你的命名空間不必附加到搜索路徑以便使用'::'符號,實際上是相反的。

搜索路徑允許通過查看附加到搜索路徑的所有名稱空間來選擇符號。

所以,正如Hadley告訴你的那樣,你只需要使用devtools :: load_all(),這就是全部...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM