Rubyのシングルトンメソッドとシングルトンクラス
シングルトン・メソッド
Rubyでは、1つのオブジェクトにメソッドを追加することができ、このような1つのオブジェクトに対してのみ動作するメソッドをシングルピースメソッドと呼びます
コード例
str = "just a regular string"
def str.title?
self.upcase == self
end
str.title? # => false
str.methods.grep(/title?/) # => [:title?]
str.singleton_methods # => [:title?]
str.class # => String
String.title? #=> NoMethodError
また、上記で使用した define メソッドに加えて、Object#define_singleton_method メソッドでシングルトン・メソッドを定義することができます。
シングルトン・メソッドとクラス・メソッドの比較
前のノートで述べたように、Rubyではクラスもオブジェクトであり、クラス名は単なる定数なので、クラス上のメソッドを呼び出すことは、オブジェクト上のメソッドを呼び出すことと実質的に同じになります。
クラスメソッドの本質は、クラスのシングルトン・メソッドであることで、実際、シングルトン・メソッドの定義とクラスメソッドの定義を比較すると、同じものであることがわかります
def obj.a_singleton_method; end
def MyClass.another_class_method; end
どちらも定義を表すdefキーワードを使用
def object.method
#method body
end
上のオブジェクトは、*オブジェクトへの参照、定数クラス名、またはselfである。
クラスマクロ attr_accessor
Rubyのオブジェクトは属性を持たないので、属性のようなものが欲しい場合は、最も直接的にこのようにreadメソッドとwriteメソッド(つまりjavaでいうところのobjcのsetとgetメソッド)をそれぞれ定義する必要があるのです。
コード例
class MyClass
def my_attribute=(value)
@my_attribute =value
end
def my_attribute
@my_attribute
end
end
obj = MyClass.new
obj.my_attribute = 'x'
obj.my_attribute #=> 'x'
しかし、上記のような書き方では、属性が多い場合、Repeat Yourselfの場所があり、そこで、以下の3つのクラスマクロが使えるようになります。
- Module#attr_reader は読み込みメソッドを生成します。
- モジュール#attr_writerで書き込みメソッドを生成する
- モジュール#attr_accessorは、読み出しと書き込みの両方のメソッドを生成します。
サンプルコード
class MyClass
attr_accessor :my_attribue
end
この方がずっとすっきりしていると思いませんか?もちろん、使い方(読み込みと書き込み)は上の実装と同じです。
シングルトン・クラス
Rubyではオブジェクトのメソッドを見つける順番は「右から上」と決まっています。つまり、まずオブジェクトのクラスを右から見つけ、そのクラスのインスタンスメソッドから見つけようとし、見つからなければ祖先の鎖を下っていくことになるのです。
前回は、特定のオブジェクトに対してのみ有効なメソッドであるシングルトンメソッドについて紹介しました。
class MyClass
def my_method; end
end
obj = MyClass.new
def obj.my_singleton_method; end
まず、シングルトンメソッドはobjにはありません。objはクラスではないので、次にMyClassにはありません。そうすると、すべてのMyClassはこのメソッドを共有で呼び出せるはずで、シングルトンクラスとは言えなくなります。同じ意味で、シングルトン・メソッドは祖先連鎖の場所(superclass: Objectのような)にはありえません。正しい場所はシングルトン・クラスの中であり、それは実はirbでオブジェクトにクラスを尋ねたときに得られるクラス(obj.class)であるが、このクラスは通常のクラスとは少し異なっていることを除けば、である。メタクラスや固有クラスと呼ぶこともできる。
シングルトン・クラスを開く
Ruby では、単一のクラスへの参照を得るために 2 つの方法が用意されています。
メソッド1
class << an_object
# Own code
end
obj = Object.new
singleton_class = class << obj
self
end
singleton_class.class # => Class
シングルトン・クラスへの参照を取得するもう一つの方法は、Object#singleton_class メソッドを使用することです。
メソッド2
"abc".singleton_class # => #<Class: #<String:0xxxxxx>>
シングルピース・クラスの特徴
- 各シングルトンクラスは1つのインスタンスしか持たず(シングルトンクラスと呼ばれる理由)、継承することができない
- シングルピース・クラスは、オブジェクトのシングルピース・メソッドが存在する場所である
- シングルトン・クラス導入後のメソッド検索
上記のシングルトン・クラスの基本的な理解に基づいて、シングルトン・クラスを導入した後、Ruby のメソッド検索はそのクラス(通常のクラス)からではなく、オブジェクトのシングルトン・クラスから始めるべきで、目的のメソッドがシングルトン・クラスに見つからなければ、クラス(通常のクラス)に沿って探し始め、さらに祖先の鎖を上がっていくことになるのです。このように、シングルトン・クラスの後に開始すると、すべてがシングルトン・クラスが導入されていないときの順序に戻る。
以下のコードで、ご自身で確認することができます。
class C
def a_method
'C#a_method()'
end
end
class D < C; end
obj = D.new
シングルトンクラスを開き、シングルトンメソッドを定義する
class << obj
def a_singleton_method
'obj#a_singleton_method()'
end
end
obj.singleton_class.superclass #=> D
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Ruby正規表現とサンプルコード
-
Rubyの二分探索(dichotomous search)アルゴリズムの簡単な例
-
Ruby on Rails ラックミドルウェア基礎学習チュートリアル
-
RubyのブロックオブジェクトProcの詳細解説
-
アプレットを置き換えるHTMLスクリプトを記述するRubyの例
-
Rubyのデザインパターン開発におけるProxyパターンの利用について
-
Rubyのデザインパターンプログラミングにおけるコマンドパターンの活用を徹底分析
-
Rubyのデザインパターン。プログラミングにおけるシングルトンパターンの活用
-
Rubyにおける正規表現の使用に関する分析
-
Rubyで配列とハッシュテーブルを使う