Я не знаю, почему все предлагают, чтобы вы использовали instance_methods
и include?
когда выполняли method_defined?
работу.
class Test
def hello; end
end
Test.method_defined? :hello #=> true
НОТА
В случае, если вы переходите на Ruby с другого языка OO или вы думаете, что это 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
, ложный аргумент может точно сказать, определен лиfreeze
метод в классе String или нет. В этом случае он вернет false, потому чтоfreeze
метод унаследован от модуля Kernel от String, ноString.method_defined? :freeze
всегда вернет true, что не может сильно помочь с такой целью.method_defined?
должен быть использован в классе (напримерArray
), но вы пытаетесь использовать его в экземплярах (например[]
)Вы можете использовать
method_defined?
следующим образом:Гораздо проще, портативнее и эффективнее, чем
instance_methods.include?
кажется всем остальным.Имейте в виду, что вы не будете знать, реагирует ли класс динамически на некоторые вызовы
method_missing
, например, путем переопределенияrespond_to?
, или начиная с Ruby 1.9.2, путем определенияrespond_to_missing?
.источник
instance.class.method_defined? :upcase
На самом деле это не работает как для объектов, так и для классов.
Это делает:
Итак, с данным ответом это работает:
Но это НЕ работает:
Поэтому я использую это для классов и объектов:
Классы:
Объекты:
источник
Ответ на « Данный класс, посмотреть, если экземпляр имеет метод (Ruby) » лучше. Очевидно, в Ruby есть эта встроенная система, и я почему-то пропустил ее. Мой ответ оставлен для справки, вне зависимости.
Классы Ruby отвечают на методы
instance_methods
иpublic_instance_methods
. В Ruby 1.8 первый перечисляет все имена методов экземпляра в массиве строк, а второй ограничивает его открытыми методами. Второе поведение - это то, что вы, скорее всего, захотите, такrespond_to?
как по умолчанию ограничивается публичными методами.В Ruby 1.9 эти методы возвращают массивы символов.
Если вы планируете делать это часто, возможно, вы захотите расширить
Module
его, добавив ярлык. (Может показаться странным назначать этоModule
вместоClass
, но, поскольку именно тамinstance_methods
живут методы, лучше придерживаться этого шаблона.)Если вы хотите поддерживать как Ruby 1.8, так и Ruby 1.9, было бы удобно добавить логику для поиска как строк, так и символов.
источник
method_defined?
лучше :)Пытаться
Foo.instance_methods.include? :bar
источник
Не уверен, что это лучший способ, но вы всегда можете сделать это:
источник
Я думаю, что с
method_defined?
Rails что-то не так . Это может быть непоследовательным или что-то, поэтому, если вы используете Rails, лучше использовать что-то изattribute_method?(attribute)
.« Проверка для method_defined?» в классах ActiveRecord не работает до момента создания экземпляра »- вопрос о несоответствии.
источник
Если вы проверяете, может ли объект отвечать на ряд методов, вы можете сделать что-то вроде:
the
methods & something.methods
присоединится к двум массивам их общих / совпадающих элементов. Что-то содержит методы, которые вы проверяете, это равнозначно методам. Например:так
В этой ситуации вы захотите использовать символы, потому что когда вы вызываете .methods, он возвращает массив символов, и если вы использовали
["my", "methods"]
, он возвращает false.источник
klass.instance_methods.include :method_name
или"method_name"
, в зависимости от версии Ruby, я думаю.источник
Надеюсь, это поможет вам!
источник
В моем случае, работающем с ruby 2.5.3, следующие предложения сработали отлично:
Он вернет логическое значение true или false.
источник
Пока
respond_to?
вернет true только для открытых методов, проверка «определения метода» в классе может также относиться к закрытым методам.На Ruby v2.0 + можно проверять как публичные, так и частные наборы с помощью
источник