Как узнать, где объявлен метод ruby?
У меня есть метод ruby (деактивировать!), который находится в активном классе Record. Однако я не могу найти, где этот метод объявлен.
В этом проекте было множество разработчиков, поэтому это могло быть где угодно. Деактивируется! на несвязанный класс, но он, похоже, не вызван.
Любые идеи, как найти все суперклассы для instace, или где найти код для деактивации!?
Ответы
Ответ 1
Когда мне нужно найти, где метод объявлен в каком-либо классе, скажем, "Модель", я делаю
Model.ancestors.find {|c| c.instance_methods(false).include? :deactivate! }
Это ищет дерево предков в том же порядке, что и ruby для первого, у которого есть метод в instance_methods(false)
, который включает только не наследуемые методы.
Примечание: до ruby 1.9 методы были перечислены как строки без символов, поэтому это было бы
Model.ancestors.find {|c| c.instance_methods(false).include?('deactivate!') }
Ответ 2
Первый вопрос: был ли он реальным методом? Увеличивает ли obj.method(:deactivate!)
ошибку?
Если это не так, вы можете использовать Method#source_location
(только в Ruby 1.9, а backports
не может его поддерживать):
obj.method(:deactivate!).source_location
Если он поднимает значение NoMethodError
, он обрабатывается через method_missing
. Это затрудняет отслеживание. Если он принимает аргументы, я бы попробовал отправить неправильный тип и использовать обратную линию поднятого исключения.
Используете ли вы state_machine
? Если у вас есть переход к событию с именем :deactivate
, модель автоматически создаст метод #deactivate!
.
Ответ 3
Как первый удар, попробуйте воспользоваться функцией "Перейти к декларации" вашей среды IDE. В зависимости от того, насколько хорош ваш статический тип IDE, он должен взять вас прямо там.
Если это не сработает, установите точку останова на этот вызов, запустите отладчик и перейдите в метод.