9

一連の関数呼び出しで使用しようとしてgetいますが、オブジェクト名のルックアップは環境をスキップしているようです。例えば:

foo <- 1 # variable in .GlobalEnv

getter <- function(x) {get(x)}
getter("foo") # returns 1, which is expected

f1 <- function() {
  foo <- 2 # local variable in the function scope
  getter("foo")
}

f1() # still returns 1, would've expected to return 2

呼び出しが呼び出し元の関数の環境ではなく、グローバル環境でをf1返すのはなぜですか?foofoo

get呼び出し元の関数の環境をどのように確認しますか?設定pos = sys.parent()がうまくいかないようです。

4

2 に答える 2

16

フレームと環境の微妙な違い (フレームが環境である、または環境がフレームであるため、これはさらに微妙です) と、字句スコープと動的スコープの違いにつまずいています。parent.frameのヘルプページや、さまざまなドキュメントにまたがる他の場所に詳細がいくつかあります。

試して単純化するには:

関数には、その関数にローカルな変数が格納されるgetter独自の環境xがあります (この場合)。R はレキシカル スコープであるため、関数環境には、関数が定義されている場所によって定義される親環境 (この場合はグローバル環境) があることを意味します (別の関数内で定義されている場合、親環境はその環境になります)。関数)。

あなたが呼び出しf1て呼び出すとgetter、ゲッターは変数を見つけようとします。foo最初にそれ自身の環境を探し、そこで見つけられず、次にグローバル環境である親環境を探しfoo、値1で見つけます。

あなたの考えは、フレームが近似する動的スコープの線に沿っています。がf1呼び出されると、独自の環境 (foo値 2 が割り当てられる) を取得し、関数を呼び出しgetterます。の環境はの env (レキシカル スコープ) のfoo親ではありませんが、 の環境はから呼び出されたのでの親フレームです。親環境より。getterf1gettergetterf1f1get

要約すると、親環境は関数が定義された環境 (レキシカル スコープ) であり、親フレームは関数が呼び出されたフレーム/環境です (シミュレートされた動的スコープ)。

于 2012-09-19T17:11:02.933 に答える
6

getter親フレームを見るように定義すると、次のように機能します。

getter <- function(x) get(x, envir=parent.frame())

それで:

getter("foo")
[1] 1

f1()
[1] 2
于 2012-09-19T09:52:14.680 に答える