2016-10-06 6 views
2

これは実際には「DOではありません!しかし、..関数入力パラメータでのクロスパッシング

私はこれを書いて何が起こるかを見ました。

circit <-function(x=deparse(substitute(y)),y=deparse(substitute(x))) 
{ 
return(list(x=x,y=y)) 
} 

二つの例:

> circit() 
$x 
[1] "deparse(substitute(x))" 

$y 
[1] "deparse(substitute(y))" 

> circit(3) 
$x 
[1] 3 

$y 
[1] "3" 

注意出力に "X" と "Y" の微妙なスワップ。
私は論理に従うことができないので、誰かが引数のパーサーがこの不条理なデフォルト入力のペアをどのように処理するか説明できますか?

+1

"評価されない"評価された "y">は評価されません。ここで<評価されていないy "は' deparse(代入(x)) " "x"が評価されている間に解読される。 'deparse(substitute(x))'の代わりに、 'circit(、3 + pi^1.24)$ x'のような単純な呼び出しは、未評価の" y "呼び出しを解読するだけの評価をします。 –

答えて

3

正式な引数は約束オブジェクトであり、substitute()には約束オブジェクトの評価方法に関する特別なルールがあります。 ?substituteで説明したように、それはそれらの発現スロットではなく、それらの値を返す:それはENV 'に結合シンボルでない場合、それは次のよう

置換は、解析 ツリーの各構成要素を調べることによって行われます は変更されていません。それが約束オブジェクト、すなわち の仮引数であるか、または 'delayedAssign()'を使用して明示的に作成された場合、約束の 表現スロットがシンボルを置き換えます。 普通変数であれば、 'env'が '.GlobalEnv'でない限り、その値が置換されます。この場合、シンボルは変更されません。

これをより明確にするには、プロセスを詳しく調べることをお勧めします。最初のケースでは、指定された引数を持たないcircuit()を呼び出します。したがって、circuit()は、デフォルト値であるx=y=を使用します。

xの場合、それはdeparse(substitute(y))を評価することによってその値が取得されたことを意味します。その式のシンボルyは、promiseオブジェクトである仮引数のyと一致します。 substitute()は、シンボルyを式スロットdeparse(substitute(x))を保持する式スロットに置き換えます。その式を分解すると、文字列"deparse(substitute(x))"が返され、xの値スロットに代入されます。

同様に、式deparse(substitute(x))を評価すると、yという値が得られます。 xのシンボルは、promiseオブジェクトである仮引数xと一致します。 xであるにもかかわらず、その表現スロットはまだdeparse(substitute(y))なので、それはsubstitute(x)の評価によって返されます。結果として、deparse(substitute(x))は文字列を返します"deparse(substitute(y))"

+0

この回答は非常に難しいです。私は 'deparse(代替(deparse(substitute(y)))')の明示的なデモンストレーションがはるかに明確になったと思います。 – eddi

+0

Rは単なる爆発ではなく、かつての約束をたどるだけであることも興味深い。 – eddi

+0

ありがとうございます。私はそれが約束の遅れに基づいていると考えましたが、その流れをずっと続けていませんでした。 –

関連する問題