読者です 読者をやめる 読者になる 読者になる

MogLog

メモというか日記というか備忘録というか

【Ruby】変数参照と定数参照

変数参照
変数とは「単純に値につけられた名前」のこと。
変数を作成するのは、代入式であり、このときに値も代入される。
代入式の左辺以外の場所で変数名が現れた際は、式を参照しており、変数の値に評価される。

one = 1.0 # これは代入式
one # この変数参照式は、1.0と評価される


変数は、式の中で出現する際にはいつでも、名前空間で修飾されない単純な形式である。
式の中に「.」や「:」が含まれている場合には、その式は定数かメソッド呼び出しの参照になっている。

Math::PI # 定数参照
item.price # item変数が保持する値のpriceというメソッド呼び出し


○ 未初期化変数
一般に変数を式で使うときは、あらかじめ変数に値を代入し、初期化しておくべき。
しかし、Rubyは特定の条件のもとでは初期化されていない変数を使うことを認めている。
ただし、使ってもよい条件は、変数の種類によって異なる。

<クラス変数>
使う前に必ず、代入しておかなければならない。値が代入されていないクラス変数が参照されると、RubyはNameErrorを起こす。

[115] pry(main)> @@class
NameError: uninitialized class variable @@class in Object
from (pry):27:in `__pry__'


インスタンス変数>
初期化されていないインスタンス変数を参照すると、Rubyはnilを返す。

[112] pry(main)> @instance
=> nil


グローバル変数
インスタンス変数と同様に、参照するとnilを返す。

[105] pry(main)> $global
=> nil


<ローカル変数>
ローカル変数の参照は、メソッド呼び出しのように見えてしまう。
Rubyインタプリタは、ローカル変数に対する代入を検出すると、それが変数であってメソッドではないことを知ることができるので、変数名が現れた時には値を返せる。
そして、代入を検出していない場合には、Rubyはその式をメソッド呼び出しとして扱う。その名前のメソッドが存在しない時には、RubyはNameErrorを起こす。

[99] pry(main)> local
NameError: undefined local variable or method `local' for main:Object
from (pry):24:in `__pry__'

一般的には、初期化されていないローカル変数を使おうとすると、エラーが起こる。しかし、注意しなければならないことが1つある。
Rubyインタプリタ「変数に対する代入式を検出すると、その変数は存在するようになる」ということ。実際にその代入が行われなくても、変数は作られる。作られたが値が代入されていない変数にはnilが与えられる。

[76] pry(main)> var
NameError: undefined local variable or method `var' for main:Object
from (pry):18:in `__pry__'
[77] pry(main)> var = 0 if false
=> nil
[78] pry(main)> var
=> nil



定数参照
Rubyの定数はプログラムの実行中、値が一定に保たれることになっていること以外は、変数と同じようなもの。
Rubyインタプリタは定数が一定の値を保つことを強制しないが、プログラムが定数の値を書き換えると警告メッセージを出す。
定数の可視性はグローバル変数と同様であり、スコープに制限されず、Rubyプログラムのあらゆる位置からアクセスすることができる。

グローバル変数との違いは、「定数はクラスとモジュールの名前空間に定義することができ、その場合は可視性が暮らすやモジュールによって制限される」というところにある。

定数参照はときに複雑な式になる場合もある。
この場合、定数が定義されているクラス、モジュールと定数名を区切るために「::」が使われる。
「::」の左辺は、クラス、モジュールと評価される任意の式でよい。
「::」の右辺は、そのクラスやモジュールで定義されている定数の名前である。

Conversion::CM_PER_INCH # Conversionモジュールで定義されている定数
modules[0]::NAME # 配列要素によって定義されている定数