2012-02-02 3 views
5

可能性の重複:
Why a = a is nil in Ruby?なぜRubyでは未定義の変数を自分自身に割り当ててもらえないのですか?

未定義の変数を使用してRubyで、私たちが言うもの、"奇現象"があります。それはこのようなものだ:

# irb session follows 
# 
foo  # undefined local variable or method 'foo' 
bar  # same for 'bar' 
foo = bar # still same for 'bar' 
foo = foo # nil - HUH? 
foo  # is now set to nil!? 

なぜ私はRubyで自身への未定義の変数を割り当て、nilを得ることができますか?

ここではRuby 1.9.3を使用しています。私はこれがで本当かもしれない他のどのバージョンかわからない。

(彼hilarious talkでこれを証明するためのゲイリーベルナールに感謝します。)

+1

おそらく 'foo = foo'は2つのステップで評価されます。最初の変数はデフォルト値で変数を宣言し、2番目の変数はそれをそれ自身に割り当てます。 – millimoose

答えて

2

無記号があるため、すべてがオブジェクトであるという考えを、Rubyで魔法です。実際には割り当てられるシングルトンの無制限オブジェクトがあります。あなたは存在に

foo = bar 

「foo」という変数スプラングを行なったし、値として魔法のnilオブジェクトを取ったとき。あなたが代入を行う前に、Rubyはfooが何であるかを知る方法を持っていませんでした(それは変数ですか、メソッド呼び出しですか?)。しかし、代入を行うと変数として扱い始めます。

+0

さて、 'foo = foo'は、これまでのステートメントがなくても動作します。 –

+0

それは確かに、同じ理由からです。無関心は物事ではありません - それは未定義の値の単なるプレースホルダーです。問題は割り当てです。Rubyが代入を認識すると、 "="の左側のトークンを変数として扱うことを "決定"します。 – theglauber

+1

@theglauber、それは 'foo = foo'を説明していません。 'foo = bar'の場合、fooとbarの両方が未定義の場合、例外は引き続き発生します。 'foo = foo'の動作が奇妙なのは、ルビインタプリタが式の評価の前に初期化を実行するためです。本質的には、左手にfooはnilに入る。インタプリタが式の評価に達して割り当てを行うときには、右側のfooは既に初期化されています。 – bigtunacan

7

例えば

if false 
    foo = 1 
end 

がnilにFOOを設定します割り当てがさえ、試行されている必要はありませんので、バーが定義されていないという事実は、実際に最も興味深い部分ではありません。私が理解しているように、ローカル変数スコープは、コードを実際に実行せずに、単に解析することで静的に決定されます。 Rubyは割り当てが起こり、ローカル変数を作成し、それをnilに設定すると考えています。 http://ruby.runpaint.org/variables#local

+0

if文で代入する変数を定義する必要はありません: 'foo = wat in false' –

関連する問題