Як перелічити всі методи об’єкта в Ruby?


113

Як перерахувати всі методи, до яких певний об’єкт має доступ?

У мене є @current_userоб'єкт, визначений у контролері програми:

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
end

І хочете побачити, які методи мені доступні у файлі перегляду. Зокрема, я хочу побачити, які методи :has_manyнадає асоціація. (Я знаю, що :has_many має надати, але хочу перевірити це.)


Щоб уточнити, ви хочете, щоб методи викликали @current_user?
Ендрю Маршалл

@Dirk, ласкаво просимо в stackoverflow! Не забудьте "перевірити" відповідь, яка найкраще відповідає на ваше запитання. Також підкажіть будь-яку відповідь на будь-яке запитання, яке вважаєте корисним / корисним.
Ларрі К

Відповіді:


211

Далі буде перераховано методи, які має клас User, що базовий клас Object не має ...

>> User.methods - Object.methods
=> ["field_types", "maximum", "create!", "active_connections", "to_dropdown",
    "content_columns", "su_pw?", "default_timezone", "encode_quoted_value", 
    "reloadable?", "update", "reset_sequence_name", "default_timezone=", 
    "validate_find_options", "find_on_conditions_without_deprecation", 
    "validates_size_of", "execute_simple_calculation", "attr_protected", 
    "reflections", "table_name_prefix", ...

Зауважте, що methodsце метод для класів та для екземплярів класу.

Ось методи, які має мій User User, які не входять до базового класу ActiveRecord:

>> User.methods - ActiveRecord::Base.methods
=> ["field_types", "su_pw?", "set_login_attr", "create_user_and_conf_user", 
    "original_table_name", "field_type", "authenticate", "set_default_order",
    "id_name?", "id_name_column", "original_locking_column", "default_order",
    "subclass_associations",  ... 
# I ran the statements in the console.

Зауважте, що методи, створені в результаті (багатьох) зв'язків has_many, визначених у класі користувача, не входять в результати methodsвиклику.

Додано Зауважте, що: has_many не додає методів безпосередньо. Натомість техніка ActiveRecord використовує Ruby method_missingта responds_toметоди для обробки викликів методу на льоту. В результаті методи не перераховані в methodsрезультаті методу.


2
Хоча це може бути не повним, оскільки деякі методи створюються лише тоді, коли викликається method_missing (наприклад, динамічні шукачі)
Фредерік Чеунг

якщо я спробую responds_to? Я отримую помилку про відсутній метод. Я запускаю це всередині application.html.erb
Дірк

@Dirk - можливо, методу немає ... Я пропоную вам подати нове запитання, де ви покажете, що таке ваші визначення AR-класу, а потім запитайте про конкретні методи, які, на вашу думку, має надати has_many. Також у вас є відповідність: належить_то? Правила капіталізації та плюралізації рейлів для АР призвели до багатьох збитків ...
Ларрі К

@Larry. Дякую - я можу отримати список за допомогою .to_yaml. Виглядає так: --- -: ескізи -: sketch_ids -: ескізи = -: sketch_ids = -: before_add_for_sketches -: before_add_for_sketches? <багато пропущених> ........ як я можу отримати доступ до цих методів? (вказуючи мені на оцінку документації теж :)
Дірк

У документах для: has_many показує , що багато хто з методів, які додаються. Інші є новими для пізніших версій Rails. До них відносяться «before_add_for» і т.д. Вони «Асоціація Callbacks» - бачити , що частина цього документ
Ларрі K

9

Модуль # instance_methods

Повертає масив, що містить назви загальнодоступних та захищених методів екземпляра у приймачі. Для модуля це загальнодоступні та захищені методи; для класу вони є методами екземпляра (не однотонними). Без аргументу або з аргументом, який не відповідає дійсності, методи екземпляра в моді повертаються, інакше повертаються методи в суперкласах mod і mod.

module A
  def method1()  end
end
class B
  def method2()  end
end
class C < B
  def method3()  end
end

A.instance_methods                #=> [:method1]
B.instance_methods(false)         #=> [:method2]
C.instance_methods(false)         #=> [:method3]
C.instance_methods(true).length   #=> 43




1

Припустимо, користувач has_many повідомлень:

u = User.first
u.posts.methods
u.posts.methods - Object.methods

1

Викласти на відповідь @ clyfe. Ви можете отримати список методів вашого примірника, використовуючи наступний код (якщо припустимо, що у вас є клас об'єкта з назвою "Парсер"):

Parser.new.methods - Object.new.methods

1

Якщо ви шукаєте список методів, на які відповідає екземпляр (у вашому випадку @current_user). Відповідно до методів рубінової документації

Повертає список імен загальнодоступних та захищених методів obj. Сюди ввійдуть усі методи, доступні предкам Obj. Якщо необов'язковий параметр false, він повертає масив загальнодоступних та захищених однотонних методів, масив не буде включати методи в модулі, включені в obj.

@current_user.methods
@current_user.methods(false) #only public and protected singleton methods and also array will not include methods in modules included in @current_user class or parent of it.

Крім того, ви також можете перевірити, чи метод може викликати об'єкт чи ні ?.

@current_user.respond_to?:your_method_name

Якщо ви не хочете методів батьківського класу, тоді просто відніміть методи батьківського класу.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.