（Rの）環境問題について　その７。


http://qiita.com/items/325bdf48f4f4885a86f1 と
http://qiita.com/items/35184390984975ec7c6d と
http://qiita.com/items/7fdb523a05a2e0b12f35 と
http://qiita.com/items/1cb4a7a05b026a0cf2bb と
http://qiita.com/items/a0a926c9e01aebb6261a と
http://qiita.com/items/6a2f6b7e21cd00f5098e の続き。

## パッケージにまつわる環境

パッケージorzにまつわる環境は二つ有ります。
1. namespace:orz
2. package:orz

通常のサーチパスでアクセスするのは2の`package:orz`です。
パッケージ内の関数を呼び出した時には、1の`namespace:orz`内が先にアクセスされます。

なんでこんなややこしい事になってるのか、っていう話になります。

## パッケージは色々隠してる

Rには無数のパッケージが有ります。各パッケージはそれぞれ勝手に変数の名前をつけています。名前空間を導入する意義は、名前の衝突を防ぐことです。このためには、外からパッケージにアクセスできる変数を出来る限り必要最小限にするべきです、というのが一般論です。

パッケージを作る際には、パッケージ内部からしか使わない変数（主に補助的な関数）をたくさん作ります。これにパッケージ外からアクセスできると、名前衝突の可能性が超高まります。なので、パッケージ作成者は外からアクセスして欲しい変数を指定することで、それ以外の変数にはアクセスできないようにします。

大雑把に言うと、`pakcage:orz`には、外からアクセスできる変数のみが、`namespace:orz`には、そうではなくパッケージ内部で作成されたすべての変数がある、と考えてもらったらいいと思います。

これは実際に以下のように調べられます。

`namespace:orz`の場合。

```R
> e <- environment(rnorm)
> e # rnormの環境、つまり namespace:stats
<environment: namespace:stats>
> head(ls(e, all = TRUE)) # 環境内の変数を全部リストアップして（先頭のみ表示）
[1] ".__NAMESPACE__."      ".__S3MethodsTable__." ".add.dendrInd"        ".asSparse"            ".cbind.ts"            ".check_vars_numeric" 
> length(ls(e, all = TRUE)) # 環境内の変数の数
[1] 1003
```

`package:orz`の場合。

```R
> g <- as.environment("package:stats")
> g # searchパス上のpackage:stats環境
<environment: package:stats>
attr(,"name")
[1] "package:stats"
attr(,"path")
[1] "/Library/Frameworks/R.framework/Versions/2.15/Resources/library/stats"
> head(ls(g, all = TRUE)) # 同じようにリストアップ。
[1] ".checkMFClasses" ".getXlevels"     ".MFclass"        "acf"             "acf2AR"          "add.scope"      
> length(ls(g, all = TRUE)) # 環境内の変数の数
[1] 505
```

というわけで、statsパッケージのnamespace環境の中には1003個の変数があって、このうち外からアクセス出来るpackage環境の中には505個ある、というのがわかると思います。

ね。

## 環境の中に隠された変数にアクセスする

FAQですが、じゃあ私は`namespace`の中だけにある変数にアクセス出来ないんですかー、ってよく聞かれます。できます。`get`か`:::`（３コロン演算子を使えばいいです）。
`get`も隠された変数にもアクセスできます。これはどうなんでしょう？

```R
> .asSparse
 エラー：  オブジェクト '.asSparse' がありません  # 普通は見つからない
> stats:::.asSparse # トリプルコロン
function (m) 
{
    if (is.null(tryCatch(loadNamespace("Matrix"), error = function(e) NULL))) 
        stop("contr*(.., sparse=TRUE) needs package \"Matrix\" correctly installed")
    as(m, "sparseMatrix")
}
<bytecode: 0x11986eea8>
<environment: namespace:stats>
> get(".asSparse", environment(rnorm)) # get
function (m) 
{
    if (is.null(tryCatch(loadNamespace("Matrix"), error = function(e) NULL))) 
        stop("contr*(.., sparse=TRUE) needs package \"Matrix\" correctly installed")
    as(m, "sparseMatrix")
}
<bytecode: 0x11986eea8>
<environment: namespace:stats>
```

## Imports/depends

ここまでくるとパッケージ作成講座で環境講座ではなくなってくるんですが、一応簡単に書いておきます。

### Importされた関数群は外からは使えない

多くのパッケージは他のパッケージの機能を使います。これはつまり、他のパッケージの環境内の変数（関数）にアクセスする、ということになります。パッケージが他のパッケージを**インポート**している場合、

```R
> # 環境をたどる関数。
> f <- function(e = parent.frame()) while (!identical(e, emptyenv())) {print(environmentName(e)); e <- parent.env(e)}
```

`stats`パッケージの`rnorm`を呼び出したとき。

```
rowse[2]> debug(rnorm)
Browse[2]> rnorm(1)
debugging in: rnorm(1)
debug: .Internal(rnorm(n, mean, sd))
Browse[4]> f()
[1] ""
[1] "stats" # stats名前空間
[1] "imports:stats" # ←これこれ。
[1] "base"
# … snip
[1] "Autoloads"
[1] "base" # package:base
```

この`imports:stats`には何があるのかというと、

```R
> getNamespaceInfo("stats", "imports")
$base
[1] TRUE

$graphics
  .filled.contour            abline            arrows         assocplot              axis              Axis         axis.Date      axis.POSIXct           axTicks           barplot 
".filled.contour"          "abline"          "arrows"       "assocplot"            "axis" 
# 以下略
```

です。

注意することなんですが、あるパッケージの`imports`環境は、外からアクセスできません。

`Hmisc`パッケージのimports環境には、

```R
> lapply(getNamespaceInfo("Hmisc", "imports"), head)
$base
[1] TRUE

$methods
  .__C__.environment   .__C__.externalptr          .__C__.name          .__C__.NULL         .__C__.Other              .__C__( 
".__C__.environment" ".__C__.externalptr"        ".__C__.name"        ".__C__.NULL"       ".__C__.Other"            ".__C__(" 

$lattice
     llines     lpoints   lsegments 
   "llines"   "lpoints" "lsegments" 

$cluster
  clara 
"clara" 
```

とありますが、例えば`lattice`の`llines`は、`library(Hmisc)`したあとにHmiscの中の関数からは呼び出されますが、`library(lattice)`とかして明示的に読み込まない限り、それ以外の環境からは使えません。

### dependsは要するにlibrary(それ)

一方、`depends`の場合は、dependされているパッケージが、サーチパスの中に追加されます。ですので、そのdependされているパッケージのpackage環境にアクセスできるようになります。

```R
> tools::pkgDepends("Hmisc")
$Depends  # Hmiscがdependsしているパッケージ
[1] "graphics" "methods"  "splines"  "stats"    "survival" "utils"   
# … snip
```

こんな感じです。

```R
> search() # サーチパス
 [1] ".GlobalEnv"        "tools:RGUI"        "package:stats"     "package:graphics"  "package:grDevices" "package:utils"     "package:datasets"  "package:devtools"  "MacJapanEnv"      
[10] "package:methods"   "Autoloads"         "package:base"     
> library(Hmisc) # Hmiscを読み込み
> search() # 増えてる。
 [1] ".GlobalEnv"        "package:Hmisc"     "package:survival"  "package:splines"   "tools:RGUI"        "package:stats"     "package:graphics"  "package:grDevices" "package:utils"    
[10] "package:datasets"  "package:devtools"  "MacJapanEnv"       "package:methods"   "Autoloads"         "package:base"     
```

というわけで、servivalとsplinesがHmiscのあとに追加されています。ですので、servivalとsplinesの関数は普通に使えます。


これでパッケージ・名前空間関連はいいのかな。
あとは、名前空間内の関数を書き換えたり、という方法ですが、これはバッドノウハウなので別の機会にします。

なにか間違ってるところとかわからない所があったら教えてください。

つづく。次はpromiseやろう。