2016-10-06 88 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

「x」評估爲其中<非評估的「y」>是deparse(substitute(x))「call」結構在評估「x」時被解析。代替'deparse(substitute(x))',像'circit(,3 + pi^1.24)$ x'這樣簡單的調用表明「x」只是評估解析未評估的「y」調用。 –

回答

3

理解/記住的關鍵是形式參數是承諾對象,並且substitute()對它如何評估承諾對象有特殊的規則。正如在?substitute解釋的那樣,它會返回它們的表達槽,而不是他們的值:

換人通過檢查解析 樹的每個部件發生如下:如果它不在「ENV」一個約束符號,它是 不變。如果它是一個承諾對象,即一個函數的形式參數,或者使用'delayedAssign()'明確創建的,則該承諾的 表達式槽將替換該符號。如果它是一個普通變量 ,它的值將被替換,除非'env'是 '.GlobalEnv',在這種情況下該符號保持不變。

爲了使這一點更清楚,可能有助於詳細瞭解過程。在第一種情況下,您調用circuit()而不提供參數,因此circuit()使用x=y=的默認值。

對於x,這意味着它的價值通過評估deparse(substitute(y))得到。該表達式中的符號y與形式參數y(承諾對象)匹配。 substitute()用其表達式插槽替換符號y,其表達式爲deparse(substitute(x))。解析該表達式將返回文本字符串"deparse(substitute(x))",這是分配給x的值插槽的內容。

同樣,y的值通過評估表達式deparse(substitute(x))得到。符號x與正式參數x(承諾對象)相匹配。儘管的值x是別的,但它的表達槽仍然是deparse(substitute(y)),所以這是通過評估substitute(x)返回的結果。結果,deparse(substitute(x))返回字符串"deparse(substitute(y))"

+0

這個答案很難遵循。我會發現'deparse(替代(deparse(substitute(y))))'更明確。 – eddi

+0

R也不是簡單地爆炸,而是隻遵循一次承諾。 – eddi

+0

謝謝。我認爲這是基於承諾的延遲,但並沒有一直遵循這個順序。 –