回答:
なぜ誰があなたが使うべきだと示唆しているのかinstance_methods
、そしてinclude?
いつmethod_defined?
仕事をするのか、私にはわかりません。
class Test
def hello; end
end
Test.method_defined? :hello #=> true
注意
別のオブジェクト指向言語から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型の列)の両方があります。
String.instance_methods(false).include? :freeze
、false引数は、freeze
メソッドがStringクラスで定義されているかどうかを正確に示します。この場合、freeze
メソッドはカーネルモジュールから文字列によって継承されるため、falseをString.method_defined? :freeze
返しますが、常にtrueを返します。これは、このような目的にはあまり役立ちません。
method_defined?
クラス(たとえばArray
)で使用する必要がありますが、インスタンス(たとえば[]
)で使用しようとしています
method_defined?
次のように使用できます。
String.method_defined? :upcase # => true
instance_methods.include?
他の誰もが提案しているよりもはるかに簡単で、移植性があり、効率的です。
method_missing
たとえば、再定義respond_to?
することによって、またはRuby 1.9.2以降に定義することによって、クラスがを使用した呼び出しに動的に応答するかどうかはわかりませんrespond_to_missing?
。
instance.class.method_defined? :upcase
実際、これはオブジェクトとクラスの両方では機能しません。
これは:
class TestClass
def methodName
end
end
与えられた答えで、これはうまくいきます:
TestClass.method_defined? :methodName # => TRUE
しかし、これは機能しません:
t = TestClass.new
t.method_defined? : methodName # => ERROR!
だから私はこれをクラスとオブジェクトの両方に使用します:
クラス:
TestClass.methods.include? 'methodName' # => TRUE
オブジェクト:
t = TestClass.new
t.methods.include? 'methodName' # => TRUE
「クラスが与えられたら、インスタンスにメソッド(Ruby)があるかどうかを確認する」への回答の方が優れています。どうやらRubyにはこの機能が組み込まれており、どういうわけかそれを逃しました。いずれにせよ、私の答えは参考にさせていただきます。
Rubyクラスはメソッドinstance_methods
とに応答しますpublic_instance_methods
。Ruby 1.8では、1つ目はすべてのインスタンスメソッド名を文字列の配列でリストし、2つ目はパブリックメソッドに制限します。2番目の動作もrespond_to?
、デフォルトでパブリックメソッドに制限されているため、最も可能性が高い動作です。
Foo.public_instance_methods.include?('bar')
Ruby 1.9では、これらのメソッドはシンボルの配列を返します。
Foo.public_instance_methods.include?(:bar)
これを頻繁に行うことを計画している場合Module
は、ショートカットメソッドを含めるように拡張することをお勧めします。(これをのModule
代わりにに割り当てるのは奇妙に思えるかもしれません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の両方をサポートする場合は、文字列とシンボルの両方を検索するロジックを追加するのにも便利です。
method_defined?
良いです:)
試す Foo.instance_methods.include? :bar
method_defined?
Rails には何か問題があると思います。一貫性がないか何かである可能性があるため、Railsを使用する場合は、から何かを使用することをお勧めしますattribute_method?(attribute)
。
「ActiveRecordクラスでのmethod_definedのテストは、インスタンス化するまで機能しません」とは、矛盾についての質問です。
オブジェクトが一連のメソッドに応答できるかどうかを確認する場合は、次のようにすることができます。
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を呼び出すとシンボルの配列が返され["my", "methods"]
、使用した場合はfalseが返されるため、シンボルを使用する必要があります。
class Foo
def self.fclass_method
end
def finstance_method
end
end
foo_obj = Foo.new
foo_obj.class.methods(false)
=> [:fclass_method]
foo_obj.class.instance_methods(false)
=> [:fclass_method]
これがあなたに役立つことを願っています!