2012-02-14 11 views
11

環境 "名前空間:統計" をつかむことができますし、 "パッケージ:統計"パッケージ/名前空間環境で同じ名前の関数の値/参照の等しいか?

ns = getNamespace("stats") 
pkg = as.environment("package:stats") 

は今の両方で機能 "SD" を取得することができます:

nsSd = get("sd" , envir = ns , inherits = FALSE) 
pkgSd = get("sd" , envir = pkg , inherits = FALSE) 

は、彼らは同じですか?彼らです!しかし、「同じ」とはどういう意味ですか?参照または価値の平等?

identical(nsSd , pkgSd) 

これはFALSE次返すので、参照平等を意味します

test1 = function() {} 
test2 = function() {} 
identical(test1 , test2) 

しかし、それは本当ならば、それは環境のフレームは、関数オブジェクトと一緒に関数ポインタを含むことができることを意味します。この問題をさらに複雑にすることは、関数がある環境で "生きている"ことができるという事実ですが、関数はその実行環境が別の環境であることを伝えることができます。部屋SoDAは答えを持っていないようです(その濃密な本、多分私はそれを逃した!)

私は決定的な答えをしたいと思います。次のうち正しいものはどれですか?または、ここに偽の三角法がありますか?

  1. nsSdpkgSdpkgSd内のオブジェクトは、その実行環境
  2. nsSdpkgSdとしてnsを有している(他の各 のコピーが)2つの異なるオブジェクトは、同じオブジェクトへのポインタされています。
  3. nsSdpkgSdへのポインタであり、そのようなものとして、彼らはこれは主にあなたの主な質問への答えではありません同じ
+0

内部の 'same'関数のcコードを見てみる価値があります。 http://svn.r-project.org/R/trunk/src/main/identical.c –

+0

あなたは人生をあまりにも複雑にしていると思います。私たちは知っている* 'sd()'関数が1つしかないので、表示される違いはそれぞれenvironemntとnamespaceを経由するアクセスパスによるものです。 –

+0

R内部のマニュアルによれば、関数の型は 'CLOSXP'です。マッチするポインタは同じものとしてカウントされ、そうでない場合は、同じ 'formals'、' body'、 'CLOENV(x)'が何であるかをチェックします。 –

答えて

5

彼らは、同じオブジェクトへのポインタであります。このanswer to another questionを使用すると、2つのオブジェクトがメモリ内の同じ場所を参照しているかどうかを確認できます。

are_same <- function(x, y) 
{ 
    f <- function(x) capture.output(.Internal(inspect(x))) 
    all(f(x) == f(y)) 
} 

are_same(nsSd, pkgSd) #TRUE 
are_same(1:5, 1:5) #FALSE 
+0

ここに余分なマイルに行くことに多くの感謝! – SFun28

+0

私は感謝の気持ちを表明するためにあなたに賞金を授与しました(24の待機期間が満了したとき) – SFun28

+0

非常に寛大なあなた。私は使用することができてうれしい。 –

4

として扱われます。しかし、その問題については、私はDirkに同意します:ただ1つのsd()関数があり、状況に応じて異なるスコープパスでアクセスすることができます。たとえば、コマンドラインでsd(x)と入力すると、sdという名前に対応する関数が、package:stats環境のフレームのエントリを介して検出されます。 stats:::sd(x)と入力するか、パッケージの別の関数がsd(x)を呼び出すと、それはnamespace:stats環境での検索で検出されます。


代わりに、私はちょうどあなたの例では、本当にidenticalに評価されないオブジェクトの「参照の等価」については何も意味しないtest1()test2()を使用してポイントを作りたかったです。 str()によって明らかにされたものを2でidenticalではない本当の理由を確認するには、その構造を見て:

test1 <- function() {} 
test2 <- function() {} 
identical(test1 , test2) 
# [1] FALSE 

str(test1) 
# function() 
# - attr(*, "srcref")=Class 'srcref' atomic [1:8] 1 13 1 25 13 25 1 1 
# .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x01613f54> 

str(test2) 
# function() 
# - attr(*, "srcref")=Class 'srcref' atomic [1:8] 1 13 1 25 13 25 1 1 
# .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x01615730> 

あなたは上記のコードボックスの右側に上をスクロールした場合、あなたは2つの機能ということがわかりますその属性の1つ、つまりソースファイルに関連付けられた環境が異なります。 (私はその属性についてあまりよく分かりませんが、それはここではあまり関係ありません。ポイントは、彼らがidenticalではないということです!あなたが作成していますすべての機能をsourcefileの属性データを保持しないRを伝える場合)

は、identical(test1, test2)の「予想外の行動が消える:

options(keep.source=FALSE) 
test1 <- function() {} 
test2 <- function() {} 
identical(test1 , test2) 
# [1] TRUE 
+0

ありがとう、ジョシュ!これは洞察力のある投稿でした。私はChambersがre:sourcefile属性=)を呼び出していると感じます。 – SFun28

+0

@ SFun28 - あなたのところに戻ってきてくれてうれしいです。 Re:ChambersのSoDA、 "dense"は本の素晴らしい記述です。私にとって驚くべきことは、そこに無駄なページがないということです。それは本当にあなたがそれを読んで何か努力を返す、私は感謝しています。乾杯。 –

+0

合意しました...良いものでいっぱいのチョック。この記事は、Rがどのように検索して物事を見つけたかについてのブログ記事を書くための探求の中で私の「行方不明のリンク」を表しています。過去の投稿、部屋、その他の情報源からの私の調査結果の蓄積と、 'search()'より深い試み。私は、1人の出典が、そのプロセスを説明しやすいとは考えていません。私はそれを投稿する前に、あなたに批評のための事前コピーを送るのが大好きです。 – SFun28

関連する問題