Rubyオブジェクトモデルの概要

4585 ワード

1.横検索
今日は主にRubyオブジェクトモデルについて簡単に話します.簡単と言っても簡単です.Rubyの中ですべてがオブジェクトであることを知っていれば.難しいといえば、確かに他の言語とは少し違います.ここで簡単に言えば、次のコードを見てみましょう.
[1] pry(main)> a = "lanzhiheng"
=> "lanzhiheng"
[2] pry(main)> a.class
=> String
[3] pry(main)> a.class.class
=> Class
[4] pry(main)> a.class.class.class
=> Class

この文法はよく知っているでしょう.ここでは、文字列"lanzhiheng"を作成し、aに値を割り当てます.ここで、aは、Stringのタイプの一例である.String型はClass型の一例であり、中国語で言えば の一例である. はまた の一例である.だから (Classタイプ)は「最も原始的」なタイプだと思います.私たちは一応この方法を横検索と呼んでいます.各オブジェクトのclassプロパティによって、その属するタイプを見つけます.
2.縦方向の検索
横検索があればもちろん縦検索がありますが、Rubyではsuperclass属性でクラスの親を検索しています.次の実行結果を見ることができます.
[18] pry(main)> a = "lanzhiheng"
=> "lanzhiheng"
[19] pry(main)> a.superclass
NoMethodError: undefined method `superclass' for "lanzhiheng":String
from (pry):19:in `__pry__'
[20] pry(main)> a.class
=> String
[21] pry(main)> a.class.superclass
=> Object
[22] pry(main)> a.class.superclass.superclass
=> BasicObject
[23] pry(main)> a.class.superclass.superclass.superclass
=> nil

このアクセスチェーンはよく知っていますか?aは通常のオブジェクトであり、親がいないため、ここではsuperclassのプロパティにアクセスするとエラーが表示されます.次に、Stringの親クラスに継承チェーンを介してアクセスします.発見結果はこのようなString -> Object -> BasicObjectであった.よし、ここまで来ればよかった.このBaseObjectは最も基本的なクラスであるため、すべてのクラスはそれから継承されています.しかし、開発に多く使われているのはObject類で、BasicObjectよりも多くの基本的な方法が含まれています.このような親を探す方法を縦検索と呼ぶ.一歩一歩上へ祖先を検索します.
オブジェクトの祖先チェーンを取得するには、そうしなければなりませんか?もちろんいいえ、もっと簡単な方法があるに違いありません.
[34] pry(main)> a.class.ancestors
=> [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]

これは、String のすべての祖先クラス(それ自体を含む)を取得することができる.でも違うよ、明らかに何かが増えた!!!多く出てきたものをModuleと言います.クラスの拡張に使用でき、Ruby On Railsというフレームワークにはこのようなものがたくさん使われています.しかし、今日議論されているのはクラスです.ここではあまり言いません.モジュールは私たちが必要とする ではないからです.このように取り除くことができます
[35] pry(main)> a.class.ancestors.select {|item| item.is_a?(Class) }
=> [String, Object, BasicObject]

祖先を取得した後、selectによって不要なModuleをスクリーニングした.実はこれは適当な方法にすぎないので、もっと言ってみてください.
[38] pry(main)> Class.superclass
=> Module
[40] pry(main)> Module.class
=> Class
Moduleクラスは の親であり、Module の例でもある.これは変なことだ.しかし、これは私たちが同じ方法でModuleをスクリーニングできないことを示しています.
[41] pry(main)> a.class.ancestors.select {|item| item.is_a?(Module) }
=> [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]
String の祖先チェーン全体は実はModuleです.しかし、Classに属しているのにModuleとは限らないので、とりあえずそうしましょう.
3.単品方法
従来のプログラミングでオブジェクトにメソッドを追加したい場合は、メソッドが属するクラスまたはその親クラスで必要なメソッドを定義します.ルビーの中で私たちはもっと簡単にこのことを完成することができます.単一のメソッドでは、単一のオブジェクトにメソッドを直接バインドできます.次の例を見てみましょう.
a = "hello lan"
b = "hello world"

def a.goodbye; "good bye" end

実行結果
[57] pry(main)> a.goodbye
=> "good bye"
[58] pry(main)> b.goodbye
NoMethodError: undefined method `goodbye' for "hello world":String
from (pry):58:in `__pry__'

この方法はオブジェクトaにのみバインドされているが、オブジェクトbにはその姿がないことがわかる.これにより、プログラムの柔軟性がある程度向上します.オブジェクトの追加方法では、クラスの動作を再定義する必要はありません.関連するオブジェクトにバインドするだけで、中毒になりませんか?
4.単品類
これらの知識は一般的な開発にとって基本的に十分です.もちろんここで単品類に言及するのはRubyが他の言語と少し違うところを表したいからです.単品クラスもクラスですが、デフォルトでRubyはそれを隠しています.単品類については、今日は軽く食べて、まずそれが何なのか見てみましょう.
[62] pry(main)> a.singleton_class
=> #>
[63] pry(main)> a.singleton_class.instance_methods.grep /good/
=> [:goodbye]
[64] pry(main)> a.singleton_class.class
=> Class

上から単品クラスは本当にクラスであり,継承チェーンでは与えられていないが,確かにクラスであることがわかる.さらに、我々が定義した単一メソッドgoodbyeは、実際にはこのクラスのインスタンスメソッドである.ただし、このクラスのインスタンスは1つだけがオブジェクトaであるため、このメソッドにアクセスできるのはそれだけです.また、単一のクラスで新しいオブジェクトを作成することはできません.
[70] pry(main)> k = a.singleton_class.new
TypeError: can't create instance of singleton class
from (pry):70:in `new'

我々は,単一クラスのインスタンスメソッドを定義することによって,単一クラスに対応するオブジェクトにメソッドをバインドした.これはルビーのかなり良い特性だと思います.
今日はここまでにしましょう.
Happy Coding !! _