2.変数と定数
1.変数とは
変数とは、値(オブジェクト)に付けられた名前のようなものです。
こうして名前をつけることで、変数からオブジェクトを参照することができるようになります。
参照というのは、データそのものではなくオブジェクトのある場所や識別番号を指します。
そして、そのオブジェクトを取得することを参照するといいます。

変数は4種類あり、プリフィクス(接頭語)による字句規則があります。
また、未初期化の状態でも使用することができ、その際の値は nil です。
2.ローカル変数
おそらく最も使われる変数だと思います。
この変数は、最も短命で代入された場所のみで使用できます。

未初期化時の値は、nil ですが、初期化されていない変数は
メソッドとの区別が付かないため NameError が発生します。
代入式があれば、たとえ実行されていなくても変数と判別されます。
var = 1 if false  # 実行されない
def method
  var
end

p var     #=> nil
p method  #=> ERROR
3.インスタンス変数
先頭に @ が付けられた変数は、インスタンス内でアクセスできます。
この変数は、オブジェクトごとに別々の値を保持します。
class Hoge
  attr_accessor :value
  def initialize
    @value = 0
  end
end

h1 = Hoge.new
h2 = Hoge.new

p h1.value, h2.value  # => 0, 0
h1.value = 3
p h1.value, h2.value  # => 3, 0

また、クラスのインスタンスで作成することで、
クラスインスタンス変数とすることもできます。
インスタンス変数というよりは、クラス変数に近いものです。
クラス変数との違いは、継承されたないということです。
class A
  @a = 1
  @@b = 3
  def self.a
    @a
  end
  def self.b
    @@b
  end
end
class B < A
end

p A.a, B.a  # => 1, nil
p A.b, B.b  # => 3, 3
クラスインスタンス変数には、クラスメソッドを定義してアクセスしてください。
4.クラス変数
先頭に @@ が付けられた変数は、クラスごとに値が保持されます。
また、この変数はサブクラスへ継承されます。
class A
  @@value = 0
  def initialize
    @@value += 1
  end
  def value
    @@value
  end
end
class B < A
end

a = A.new
p a.value
b = A.new
p a.value
c = B.new
p a.value, b.value, c.value   # => 1, 2, 3
5.グローバル変数
先頭に $ がつけられた変数は、プログラム終了まで値を保持し、
どこからでもアクセスするとこができます。
$global = 0
class Hoge
  $global = 1
  def plus
    $global += 1
  end
end

Hoge.new.plus
Hoge.new.plus
p $global # => 3
6.定数
定数とは、その名の通り定められた数です。
プログラム内でその値が変わらないものを定義しますが、再代入可能です。
定数はクラスごとに定義することができ、どこからでも参照できます。

クラス定義を行った際にも定数宣言が行われ、その定数にクラスオブジェクトへの参照が作られます。
::で、クラス・モジュール内の定数を外部参照・代入する事が可能です。
HOGE = 0
class A
  HOGE = 1
end
class B < A
  HOGE = 2
  def const
    # self の定数、A クラスの定数、トップレベルの定数
    p HOGE, A::HOGE, ::HOGE
  end
end

p HOGE, A::HOGE, B::HOGE  # => 0, 1, 2
B.new.const               # => 2, 1, 0
# クラス名も定数ですので、変更されるとクラスが消えます。
A = nil                   # => WARNING
A.new                     # => NoMethodError
7.変数のスコープ
同じ変数名が有効な範囲をスコープといいます。
このスコープの違いで変数の名称が変わったと思います。
ローカルスコープ、インスタンススコープ、クラススコープ、グローバルスコープなど。

このほかにもイテレータ(反復処理)で新しい変数スコープが作成されます。
このブロック内で定義されたローカル変数は、ブロック外には定義されていません。
しかし、メソッド内のローカル変数はブロック内でも参照することが出来ます。
ですので、ブロック外で使用している変数名を使用する場合は注意してください。

ブロックというのは、{ ... } で囲まれた部分のことです。もちろん do ... end も含まれます。
a = 1
(0...10).each {|i| a = i }
p a   # => 9
p i   # => ERROR
for-in は、each メソッドを呼び出す構文ですが、こちらは新しい変数スコープを作成しません。
a = 1
for i in 0...10
  a = i
end
p a   # => 9
p i   # => 9