R の変数のスコープは基本的にレキシカルスコープである。しかしながら、evalsq
関数を利用してダイナミックスコープを実現することもできる。
レキシカルスコープ
あるスコープ内で変数が呼び出された時、自己のスコープ内でその変数が見つかからない場合は、その絶対的な親スコープから探そうとする。これがレキシカルスコープである。R は基本的にレキシカルスコープである。
x <- 10 # グローバルな変数
fA <- function() {
print(x) # fA の中に x が定義されていないため、その親スコープ内の x が利用される。(x = 10)
}
fB <- function() {
x <- 20
print(x) # fB の中に x が定義されているため、これを利用する。(x = 20)
}
fC <- function() {
x <- 30
fA() # fA の絶対的な親は一番外側の x = 10 が利用される
fB() # fB の中に x が定義されているため x = 20 が利用される
print(x) # fC の中に x が定義されているため x = 30 が利用される
}
fC()
## [1] 10 # fA()の出力
## [1] 20 # fB()の出力
## [1] 30 # print(x)の出力
ダイナミックスコープ
R は基本的にレキシカルスコープであるが、evalsq
関数を利用することでダイナミックスコープを実現できる。ダイナミックスコープは、自己のスコープに変数が見つからない場合、相対的な親スコープから探そうとする特徴がある。
x <- 10
fA <- function() {
print(evalq(x, parent.frame()))
}
fB <- function() {
x <- 20
print(evalq(x, parent.frame()))
}
fC <- function() {
x <- 30
fA() # fA の相対的な親スコープは、fC なので、x = 30
fB() # fB の相対的な親スコープは、fC なので、x = 30
print(evalq(x, parent.frame())) # fC の相対的な親スコープはグローバルなので、 x = 10
}
fC()
## [1] 30 # fA()の出力
## [1] 30 # fB()の出力
## [1] 10 # print(x)の出力
親環境
R で定義されている親環境は parent.env
と parent.frame
とがある。
parent.env | 絶対的な親環境を表す。 |
parent.frame | 現在の位置から見た相対的な親環境を表す。 |