はい、Rubyのメソッドルックアップは、Pythonのメソッドルックアップとは少し異なります。
TL:DRの答えは、Array
クラスオブジェクトから実際にlength
メソッドを取得する場合は、Array.instance_method(:length)
と書く必要があります。
unbound_method = Array.instance_method(:length)
ary = [1,2,3,4]
bound_method = unbound_method.bind(ary)
bound_method.call #=> 4
当然のことながら、これは一般的にRubyで行われていない:これは、あなたが、特定のオブジェクトにバインドし、呼び出すことができUnboundMethod
オブジェクトを取得します。
Rubyでは、クラス自体は、クラスClass
のインスタンスです。これらのクラスは、上記と彼らはなどもちろんnew
、name
、superclass
、としてそのインスタンス、メソッドを提供する方法を超えて、自分自身のメソッドを持って、それが可能はあなたのでArray
クラスオブジェクトにlength
メソッドを定義することですArray.length
と書くことができますが、これは本質的に同じ名前のインスタンスメソッドには関係しません。コアクラスにはいくつかの場所があり、実際にこれが行われる標準ライブラリがありますが、大部分はRubyでは慣用的ではありません。
方法区別Class
オブジェクトを直接に応答し、それはそのインスタンスを提供するものは、methods
とinstance_methods
方法の出力にかなりはっきりと見ることができる。
irb(main):001:0> Array.methods
=> [:[], :try_convert, :new, :allocate, :superclass, ...
irb(main):002:0> Array.instance_methods
=> [:each_index, :join, :rotate, :rotate!, :sort!, ...
一つの理由Rubyのメソッドルックアップは、Pythonでのやり方では機能しません。クラスとインスタンスの両方が異なる方法で応答する必要のあるメソッド名があるかもしれません。例えば、仮想のPersonクラスを考えてみます。Pythonで
Person.ancestors # => [Person, Animal, Organism, Object, Kernel, BasicObject]
john = Person.new(...)
john.ancestors # => [John Sr., Sally, Jospeh, Mary, Charles, Jessica]
を、当然のことながら、最初の呼び出しはエラーになります:あなたはそれはないだろう、__self__
するPerson
のインスタンスを渡さずPerson.ancestors
を呼び出すことはできません意味をなさないしかし、Personクラスの祖先はどうやって取得できますか?関数inspect.getmro(Person)
にはPerson
自体を渡します。これはPythonでは慣用的ですが、Rubyでは非常に貧弱なスタイルとみなされます。
本質的には、多くの点で類似しているにもかかわらず、特定の問題を解決するさまざまな方法がありますが、一方では良い練習やスタイルと見なされるものもあります逆に)。