2015-01-09 13 views
8

汎用関数内で変数を定義すると、そのメソッドで使用できます。例:汎用関数内のスコープR

g <- function(x) { 
    y <- 2 
    UseMethod("g") 
} 
g.default <- function() y 
g() 
[1] 2 

ただし、定義する変数の名前がfunctionパラメーターと同じ場合は発生しません。 Rはメソッドを呼び出す前にその変数を削除するようです:

g <- function(x) { 
    x <- 2 
    UseMethod("g") 
} 
g.default <- function() x 
g() 
Error in g.default() : object 'x' not found 

誰かがここで何が起こっているのか正確に説明できますか?

答えて

4

C source file that defines do_usemethodからの以下のコメントは、少なくとも何が起こっているかを示唆しています。特に2番目の列挙された項目の2番目の文を参照してください。

基本的には(2番目の点で規則のダムアプリケーションのために)、xの値はコピーされません。これは、Cコードが形式間にあるかどうかをチェックし、メソッドの評価環境に挿入された変数のリストから除外されます。

/* usemethod - calling functions need to evaluate the object 
* (== 2nd argument). They also need to ensure that the 
* argument list is set up in the correct manner. 
* 
* 1. find the context for the calling function (i.e. the generic) 
* this gives us the unevaluated arguments for the original call 
* 
* 2. create an environment for evaluating the method and insert 
* a handful of variables (.Generic, .Class and .Method) into 
* that environment. Also copy any variables in the env of the 
* generic that are not formal (or actual) arguments. 
* 
* 3. fix up the argument list; it should be the arguments to the 
* generic matched to the formals of the method to be invoked */ 
+0

私はこれが起こっている理由であることに同意します。しかし、これを回避するには、ジェネリックに送信しているオブジェクトを変更したい場合は、それを 'UseMethod()'の2番目のパラメータとして渡す必要があります。また、ジェネリック実装が少なくとも共通の第一引数を共有していればうれしいでしょう。 'g.default()'にはパラメータがないことは奇妙です。これは修正された 'x'を渡すことが期待される場所です。 – MrFlick

+0

@MrFlick - しかし、あなたが見ることができるように、 'UseMethod'の第2引数が渡されることはありません。これは、どのメソッドをディスパッチするべきかを決定するためにのみ使用されます(どんな場合でも、汎用関数呼び出しから欲しいと思われる)。私は、いくつかのメソッドの引数リストを構造化する方法に関する一般的な勧告に同意します。 –

+0

@MrFlick - あなたが望むなら、 'UseMethod()'を使って、いくつかの異なる引数の値に基づいてディスパッチすることができたことを、今までは認められませんでした。 S4クラスで何が起こるかなど)。これは、ジェネリックの本体でビットまたは前処理が必要ですが、達成するのが難しくないようです。それがよく知られているRパッケージに使われているのだろうかと思います。 –

関連する問題