餡子付゛録゛

ソフトウェア開発ツールの便利な使い方を紹介。

Rの関数の引数が参照渡しから値渡しに変わるとき

実用上はRの関数の引数は値渡しと理解しておけばよいのですが、引数を他の変数に代入したり、関数の中の関数呼び出しで使ったりする前は、参照渡しになっています。実際、

fn1 <- function(x) x^2
fn2 <- function(x, fn){
    rm("fn1", envir = parent.env(environment()))
    if(!exists("fn1", envir = parent.env(environment()))) print("fn1がありません")
    fn(x)
}
print(fn2(3, fn1))

と言う風に、計算に使う前に親環境のオブジェクトを消してしまうと、「fn2(3, fn1) でエラー: オブジェクト 'fn1' がありません」とエラーが出ますが、

fn1 <- function(x) x^2
fn2 <- function(x, fn){
    fn0 <- fn
    rm(fn0) # fn0は用済み
    rm("fn1", envir = parent.env(environment()))
    if(!exists("fn1", envir = parent.env(environment()))) print("fn1がありません")
    fn(x)
}
print(fn2(3, fn1))

他の変数に代入すると、親環境のオブジェクトを消してもエラーなく実行できます。実用上、このようなコードを書く必要は無いので、一生、気づかない人は多そうですが。