# 変数と定数

- ローカル変数
- インスタンス変数
- クラス変数
- グローバル変数
- 疑似変数
- 定数
  - 定数参照の優先順位

Ruby の変数と定数の種別は変数名の最初の一文字によって、 ローカル変数、 インスタンス変数、 クラス変数、 グローバル変数、 定数 のいずれかに区別されます。 通常の変数の二文字目以降は英数字または `_`ですが、組み込み変数の一部には 「``$`'+1文字の記号」という変数があります(組み込み変数を参照)。変数名 の長さにはメモリのサイズ以外の制限はありません。

## ローカル変数

例:

    foobar

小文字または``_`'で始まる識別子はローカル変数また はメソッド呼び出しです。ローカル変数スコープ(クラス、モジュー ル、メソッド定義の本体)における小文字で始まる識別子への最初 の代入はそのスコープに属するローカル変数の宣言になります。宣 言されていない識別子の参照は引数の無いメソッド呼び出しとみな されます。

ローカル変数のスコープは、宣言した位置からその変数が宣 言されたブロック、メソッド定義、またはクラス/モジュール定義 の終りまでです。寿命もそのブロックの終りまで(トップレベルの ローカル変数はプログラムの終了まで)ですが、例外としてブロッ クが手続きオブジェクト化された場合は、そのオブジェクトが消滅 するまで存在します。同じスコープを参照する手続きオブジェクト 間ではローカル変数は共有されます。

    # (A) の部分はスコープに入らない
    2.times {
      p defined?(v)    # (A)
      v = 1            # ここ(宣言開始)から
      p v              # ここ(ブロックの終り)までが v のスコープ
    }

    # => nil
         1
         nil           <- これが nil であることに注意
         1

宣言は、例え実行されなくても宣言とみなされます。

    v = 1 if false # 代入は行われないが宣言は有効
    p defined?(v)  # => "local-variable"
    p v            # => nil

またあまり推奨はされませんが -K オプションを指定 すれば日本語文字の識別子も使用でき、それはローカル変数とみなされます。

## インスタンス変数

例:

    @foobar

``@`'で始まる変数はインスタンス変数であり、特定の オブジェクトに所属しています。インスタンス変数はそのクラスま たはサブクラスのメソッドから参照できます。初期化されていない インスタンス変数を参照した時の値は`nil`です。

## クラス変数

例:

    class Foo
      @@foo = 1
      def bar
        puts @@foo
      end
    end

`@@`で始まる変数はクラス変数です。クラス変数はクラス定義 の中で定義され、クラスの特異メソッド、インスタンスメソッドなどから参照／ 代入ができます。

クラス変数と定数の違いは以下の通りです。

- 再代入可能(定数は警告を出す)
- クラスの外から直接参照できない(継承されたクラスからは参照／代入可能)

クラス変数はクラス自身のインスタンス変数とは以下の点で異なります。

- サブクラスから参照／代入が可能
- インスタンスメソッドから参照／代入が可能

クラス変数は、そのクラスやサブクラス、それらのインスタンスで共有される グローバル変数であるとみなすことができます。

    class Foo
      @@foo = 1
    end
    class Bar < Foo
      p @@foo += 1          # => 2
    end
    class Baz < Bar
      p @@foo += 1          # => 3
    end

モジュールで定義されたクラス変数(モジュール変数)は、そのモジュールをイ ンクルードしたクラス間でも共有されます。

    module Foo
      @@foo = 1
    end
    class Bar
      include Foo
      p @@foo += 1          # => 2
    end
    class Baz
      include Foo
      p @@foo += 1          # => 3
    end

## グローバル変数

例:

    $foobar
    $/

``$`'で始まる変数はグローバル変数で、プログラムの どこからでも参照できます(その分、利用には注意が必要です)。 グローバル変数には宣言は必要ありません。 初期化されていないグローバル変数を参照した時の値は `nil`です。

## 疑似変数

通常の変数以外に疑似変数と呼ばれる特殊な変数があります。

`self`

  現在のメソッドの実行主体

`nil`

  NilClassクラスの唯一のインスタンス

`true`

  TrueClassクラスの唯一のインスタンス。真の代表値

`false`

  FalseClassクラスの唯一のインスタンス。nilとfalseは偽を表します。

`__FILE__`

  現在のソースファイル名 *1

`__LINE__`

  現在のソースファイル中の行番号

疑似変数の値を変更することはできません。 擬似変数へ代入すると文法エラーになります。

## 定数

例:

    FOOBAR

アルファベット大文字 (`[A-Z]`) で始まる識別子は定数です。 定数の定義 (と初期化) は代入によって行われますが、メソッドの 中では定義できません。一度定義された定数に再び代入を行おうと すると警告メッセージが出ます。定義されていない定数にアクセス すると例外 NameError が発生します。

定数はその定数が定義されたクラス/モジュール定義の中(メソッド 本体やネストしたクラス/モジュール定義中を含みます)、クラスを 継承しているクラス、モジュールをインクルードしているクラスま たはモジュールから参照することができます。クラス定義の外(トッ プレベル)で定義された定数は Object に所属することになり ます。

例:

    class Foo
      FOO = 'FOO'       # クラス Foo の定数 FOO を定義(Foo::FOO)
    end

    class Bar < Foo
      BAR = 'BAR'       # クラス Bar の定数 BAR を定義(Bar::BAR)

      # 親クラスの定数は直接参照できる
      p FOO             # => "FOO"
      class Baz

        # ネストしたクラスはクラスの継承関係上は無関係であるがネス
        # トの外側の定数も直接参照できる
        p BAR           # => "BAR"
      end
    end

またクラス定義式はクラスオブジェクトの生 成を行うと同時に、名前がクラス名である定数にクラスオブジェクトを代入す る動作をします。クラス名を参照することは文法上は定数を参照していること になります。

    class C
    end
    p C    # => C

あるクラスまたはモジュールで定義された定数を外部から参照する ためには``::`'演算子を用います。また`Object`クラスで 定義されている定数(トップレベルの定数と言う)を確実に参照する ためには左辺無しの``::`'演算子が使えます。 ただしこれらの ``::`' 演算子を用いて定数に代入すること はできません。

ruby 1.8 feature: ``::`' 演算子を用いた定数への代入が可能に なりました。

例:

    module M
      I = 35
      class C
      end
    end
    p M::I   #=> 35
    p M::C   #=> M::C
    p ::M    #=> M

    M::NewConst = 777   # error--> parse error

### 定数参照の優先順位

親クラスとネストの外側のクラスで同名の定数が定義されているとネストの外 側の定数の方を先に参照します。つまり、定数参照時の定数の探索順序は、最 初にネスト関係を外側に向かって探索し、次に継承関係を上位に向かって探索 します。

例:

    class Foo
      CONST = 'Foo'
    end

    class Bar
      CONST = 'Bar'
      class Baz < Foo
        p CONST             # => "Bar"      外側の定数
        # この場合、親クラスの定数は明示的に指定しなければ見えない
        p Foo::CONST        # => "Foo"
      end
    end

トップレベルの定数定義はネストの外側とはみなされません。したがってトッ プレベルの定数は、継承関係を探索した結果で参照されるので優先順位は低い と言えます。

例:

    class Foo
      CONST = 'Foo'
    end

    CONST = 'Object'

    class Bar < Foo
      p CONST               # => "Foo"
    end

    # 以下のように明示的にネストしていれば規則通り Object の定数
    # (ネストの外側)が先に探索される
    class Object
      class Bar < Foo
        p CONST             # => "Object"
      end
    end

上位のクラス(クラスの継承関係上、およびネストの関係上の上位クラス)の定 数と同名の定数(下の例で CONST) に代入を行うと、上位の定数への代入では なく、そのクラスの定数の定義になります。

例:

    class Foo
      CONST = 'Foo'
    end
    class Bar < Foo
      p CONST               # => "Foo"
      CONST = 'Bar'         # Bar の定数 CONST を*定義*
      p CONST               # => "Bar"  (Foo::CONST は隠蔽される)
      p Foo::CONST          # => "Foo"  (:: 演算子で明示すれば見える)
    end

*1 フルパスとは限らないため、フルパスが必要な場合は `File.expand_path(__FILE__)` とする必要があります。

links: [FalseClass] [NameError] [NilClass] [Object] [Rubyの起動] [TrueClass] [ruby 1.8 feature] [クラス／メソッドの定義] [組み込み変数] [変数と定数]
reverse links: [Module] [Rubyの文法] [Rubyリファレンスマニュアル] [プログラム]