永続代入(スーパーアサインメント)演算子
Rのお話です。
永続代入演算子(<<-)というのがあります。
これを「グローバル変数への代入演算子」と勘違いして覚えてしまうような扱いをよく見る気がします。それでも基本困ることはないと思いますが、ここで正しい意味を覚えてしまいましょう。
説明
下の実行結果を見てください。
> x <- 5 # グローバル変数 > func <- function() { + super <- function() { + x <<- x + 10 # ローカル変数(super) + } + x <- 3 # ローカル変数(func) + super() + return(x) # 出力1へ + } > func() # 関数の実行 [1] 13 # 出力1 > x [1] 5 # 出力2
基本的にローカル変数に限らず、Rはその現在の環境にないオブジェクトを扱おうとすると、まずその1つ上の環境に同じ名前のオブジェクトはないか探します。あればそれを、なければさらに上の環境を探すといったところです。今回のテーマもそれに近いところがあります。
出力1, 2を見てください。永続代入演算子によってfunc関数内のローカル変数xには13が代入されていますが、グローバル変数xは実行前と変わりません。これは、代入する変数xがあるかどうか、最も近い上の環境から1つずつ順に調べていった結果、初めに見つけたfunc関数内のローカル変数xに代入を実行しているからです。
よくわからないですね。では、もしもfunc関数内のローカル変数xがなければどうなるでしょう。
> x <- 5 # グローバル変数 > func <- function() { + super <- function() { + x <<- x + 10 # ローカル変数(super) + } + # x <- 3 # ローカル変数(func) + super() + return(x) # 出力1へ + } > func() # 関数の実行 [1] 15 # 出力1 > x [1] 15 # 出力2
func関数の実行結果とグローバル変数xの出力が同じになりました。これは、super関数より上の環境におけるxの代入先が、グローバル変数xのみになってしまったためです。
ならばグローバル変数xもなくしてしまえばどうなるでしょう。グローバル環境は変数サーチの終点になります。よってこれ以上、上の環境を探すことはありませんが、変数がないので新たに変数xを生成して代入します。