2016-04-12 18 views
0

なぜ私はではないのですか?に問題があります(それはペースの良い変化です)。だから、これを調達した後、私は2つのカスタム関数、foobarが含まれているリストオブジェクトを持って、次のレイジー評価と隠れた環境がR

MyFuncs <- (function(){ 

    hidden <- function(){return('ninja')}  
    foo <- function(){paste(hidden(), 'foo')}  
    bar <- function(){paste(hidden(), 'bar')}  
    return(list(foo = foo, bar = bar)) 

})() 

を考えてみましょう。これらの関数の両方は、別の関数hiddenを参照していますが、これはそのリストの一部ではありません。 hiddenに電話することはできませんが、foobarはどちらも完璧に動作します。 Rは怠惰な評価をしているので、私はこれらが動作しないと予想していました。 fooの定義はhiddenを参照しています。fooを評価しようとすると、hiddenを評価することができないため、エラーが発生することが予想されます。

> print(MyFuncs$foo()) 
[1] "ninja foo" 
> print(MyFuncs$bar()) 
[1] "ninja bar" 
> print(MyFuncs$hidden()) 
Error in print(MyFuncs$hidden()) : attempt to apply non-function 
> foo2 <- function(){paste(hidden(), 'foo')} 
> print(foo2()) 
Error in paste(hidden(), "foo") : could not find function "hidden" 

は、次のように近い私が言うことができるように、MyFuncs下の関数は名前ではなく、検索パスにある自分の環境にあるものとして定義されています。環境とフレームの間のフィンの違いの1つに来ていますか?

+0

遅延評価は、通常、関数パラメータを参照します。私はそれが何であるかを正確には分かっていないので、あなたの質問に答える方法はわかりません。ここに疑問符があります。それは本当に環境とフレームの違いについてですか?あるいは、あなたはその質問を答えられるものに言い換えることができます。 – MrFlick

+1

Rの人々が関数を呼び出すオブジェクトは本当にクロージャであり、作成された環境へのポインタを持ちます。この場合、 'foo'と' bar'の両方に 'hidden'が含まれています。 –

+0

私は正しいと思ったかもしれないと思っていますが、これを正しい言葉で説明することはできません。読んでくれてありがとう;私はもう少しそれを打つと、明日の質問をきれいにしようとします。 – Adam

答えて

1

すべての内部機能の環境がMyFuncsのローカルスコープであることに注意してください:

MyFuncs <- (function(){ 

    hidden <- function(){return('ninja')}  
    foo <- function(){paste(hidden(), 'foo')}  
    bar <- function(){paste(hidden(), 'bar')} 
    print(environment()) ## note I added this line 
    return(list(foo = foo, bar = bar)) 

})() 

は(私はそれを実行しました。この場合には)出力します。また

<environment: 0x7fb74acd00d8> 

> environment(MyFuncs$foo) 

<environment: 0x7fb74acd00d8> 

> environment(MyFuncs$bar) 

<environment: 0x7fb74acd00d8> 

> environment(get("hidden", environment(MyFuncs$foo))) 

<environment: 0x7fb74acd00d8> 

> get("hidden", environment(MyFuncs$foo))() 

[1] "ninja"  

hidden 0123によって呼び出されるまで評価されません最初のインスタンスではですが、すべてがそのローカル関数スコープに含まれているため、存在できない理由はありません。

編集は私が明示的に遅延評価の問題に対処しなかったが、@MrFlickが言うように、これは通常、あなたが明示的delayedAssignを起動しない限り、引数を関数に適用されます。 hiddenが割り当てられ、fooまたはbarから呼び出されるまで評価されません。関数MyFuncsの環境は、実際には検索パス上にないという意味で「隠されていますが、これは変更できます。

私たちは、この名前空間を表すオブジェクトを作成することができます:我々は、検索()パスにアタッチすることができます

> env <- environment(MyFuncs$foo) 
> foo() 
Error: could not find function "foo" 
> get("foo", env)() 
[1] "ninja foo" 

を:

> attach(env, name="Myfuncs.foo") 
> search() 
[1] ".GlobalEnv" "Myfuncs.foo" [...] 
> foo() 
[1] "ninja foo" 
> hidden() 
[1] "ninja" 

そして、我々が割り当てられた名前を使用して、それを切り離し:

> detach("Myfuncs.foo") 
関連する問題