Rubyrespond_to?
では、オブジェクトに特定のメソッドがあるかどうかを確認するために使用できることを知っています。
しかし、クラスが与えられた場合、インスタンスに特定のメソッドがあるかどうかを確認するにはどうすればよいですか?
つまり、
Foo.new.respond_to?(:bar)
しかし、新しいインスタンスをインスタンス化するよりも良い方法があると思います。
Rubyrespond_to?
では、オブジェクトに特定のメソッドがあるかどうかを確認するために使用できることを知っています。
しかし、クラスが与えられた場合、インスタンスに特定のメソッドがあるかどうかを確認するにはどうすればよいですか?
つまり、
Foo.new.respond_to?(:bar)
しかし、新しいインスタンスをインスタンス化するよりも良い方法があると思います。
instance_methods
誰もがあなたが使うべきだと提案している理由と、include?
いつ仕事をするのかわかりませんmethod_defined?
。
class Test
def hello; end
end
Test.method_defined? :hello #=> true
ノート
別の OO 言語から Ruby に移行する場合、またはmethod_defined
明示的に定義したメソッドのみを意味すると思われる場合:
def my_method
end
それからこれを読んでください:
Ruby では、モデルのプロパティ (属性) は基本的にメソッドでもあります。method_defined?
メソッドだけでなく、プロパティに対しても true を返します。
例えば:
String 属性を持つクラスのインスタンスが与えられた場合first_name
:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
first_name
属性とメソッド (および String 型の文字列) の両方であるためです。
method_defined?
次のように使用できます。
String.method_defined? :upcase # => true
instance_methods.include?
他の人が提案しているように見えるよりもはるかに簡単で、移植性があり、効率的です。
method_missing
クラスが、たとえば を再定義respond_to?
することによって、または Ruby 1.9.2 以降では を定義することによって、いくつかの呼び出しに動的に応答するかどうかはわからないことに注意してrespond_to_missing?
ください。
「クラスが与えられた場合、インスタンスにメソッド(Ruby)があるかどうかを確認してください」に対する答えの方が優れています。どうやらRubyにはこれが組み込まれているようで、どういうわけか見逃していました。とにかく、私の答えは参照用に残されています。
instance_methods
Ruby クラスはメソッドおよびに応答しますpublic_instance_methods
。Ruby 1.8 では、1 つ目はすべてのインスタンス メソッド名を文字列の配列にリストし、2 つ目はそれをパブリック メソッドに制限します。respond_to?
2 番目の動作は、デフォルトでパブリック メソッドにも制限されているため、最も望ましい動作です。
Foo.public_instance_methods.include?('bar')
しかし、Ruby 1.9 では、これらのメソッドはシンボルの配列を返します。
Foo.public_instance_methods.include?(:bar)
これを頻繁に行うことを計画している場合Module
は、ショートカット メソッドを含めるように拡張することをお勧めします。Module
( this をの代わりにに割り当てるのは奇妙に思えるかもしれませんClass
が、instance_methods
メソッドが存在する場所であるため、そのパターンに合わせておくのが最善です。)
class Module
def instance_respond_to?(method_name)
public_instance_methods.include?(method_name)
end
end
Ruby 1.8 と Ruby 1.9 の両方をサポートする場合は、文字列とシンボルの両方を検索するロジックを追加するのに便利な場所です。
試すFoo.instance_methods.include? :bar
これが最善の方法かどうかはわかりませんが、いつでもこれを行うことができます:
Foo.instance_methods.include? 'bar'
オブジェクトが一連のメソッドに応答できるかどうかを確認する場合は、次のようにすることができます。
methods = [:valid?, :chase, :test]
def has_methods?(something, methods)
methods & something.methods == methods
end
これmethods & something.methods
は、共通/一致する要素で2つの配列を結合します。something.methods には、チェックしているすべてのメソッドが含まれます。メソッドと同じになります。例えば:
[1,2] & [1,2,3,4,5]
==> [1,2]
それで
[1,2] & [1,2,3,4,5] == [1,2]
==> true
この状況では、.methods を呼び出すとシンボルの配列が返され、.methods を使用すると["my", "methods"]
false が返されるため、シンボルを使用する必要があります。
klass.instance_methods.include :method_name
または"method_name"
、私が考えるRubyのバージョンによって異なります。