トップ «前の日記(2006年08月06日) 最新 次の日記(2006年08月12日)» 編集

ohai日誌

2003|12|
2004|01|02|03|04|05|06|07|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|06|08|10|11|
2008|01|02|03|04|05|07|09|
2009|01|02|
2013|06|12|
2014|01|02|03|04|06|09|10|12|
2015|04|
2016|09|
2018|02|

2006年08月08日

_ 変数/定数

今回は変数/定数関連です。

まずはインスタンス変数関連から

  • Object#instance_variables

    オブジェクトのインスタンス変数名を「文字列の配列で」返します。

  • Object#instance_variable_get
  • Object#instance_variable_set

    名前そのままです。privateメソッドではないのでクラスの外からでも 触り放題です。基本的にそういうことはやらないほうが良いのですが。

使用例は前回のattr_accessor_defaultなど。 「インスタンス変数名」をパラメータとして扱いたいときなどに使います。

  • Object#remove_instance_variable

    こういうものもあります。

次はクラス変数。おおよそインスタンス変数と同様。クラスオブジェクトは Classクラスのインスタンスで、ClassクラスはModuleクラスのサブクラスで あることに注意しましょう。

  • Module#class_variables
  • Module#class_variable_get
  • Module#class_variable_set

クラス変数をそもそもあまり使いませんし、使い道は少ないと思います。 インスタンス変数とあわせるために一通りあるのでしょう。

ローカル変数とグローバル変数には、

  • Kernel#local_variables
  • Kernel#global_variables

があります。irbやdebuggerくらいしか使い道はないでしょう。 Binding.of_callerみたいな代物と組合せればなにかが見えてくるのかも しれません。よくわかりませんけど。

定数は、同じようなものとして

  • Module.constants
  • Module#constants

上は呼び出したコンテキストにおける定数を、下はそのモジュールに属する 定数のリストを文字列の配列得ます。やはり使い道はあまりありません。 Module#constantsはRRBで使っていますがこれも特殊用途でしょう。 Module.constantsはさらに使い道が限られてきます。

定数関連はインスタンス変数と似たメソッドもあります。

  • Module#const_get
  • Module#const_set
  • Module#const_defined?
  • Module#remove_const

Module#remove_constを以下のように使うことで、警告を発さずに 定数を変更することができます。

module Bar
  Foo = 2
  remove_const(:Foo)
  Foo = 3
end

トップレベル定数はObjectクラスに定義されているので

class Object
  remove_const(:Foo)
end

などとなります。こんなことをしては定数の意味がなくなるので 基本的にはやってはいけません。ただこれにより既存のライブラリを 乗っ取るようなことができます。例えば後方互換性がないライブラリ を後方互換性があるように見せ掛けたりする等に使えます。

さらに邪悪なこととして、同じ名前を持つが実体が異なるクラスなどと いったものも作れます。

まあこのあたりバージョンが上がると変わりそうな話ではあります。

次回は、instance_evalかhook関連かの話をしようと思います。

_ Object/Module/Class/Kernel

この手のメソッドはおよそ Object/Module/Class/Kernel のいずれかに 属します。Rubyでより妙なことをしたければリファレンスの このあたりを良く読むと良いでしょう。

_ *_defined?

const_defined?はあってもinstance_variable_defined?はありませんね。


トップ «前の日記(2006年08月06日) 最新 次の日記(2006年08月12日)» 編集