Как перечислить все методы для объекта в Ruby?

Как мне перечислить все методы, к которым имеет доступ определенный объект?

У меня есть объект @current_user, определенный в контроллере приложения:

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

И хочу посмотреть, какие методы у меня есть в файле вида. В частности, я хочу посмотреть, какие методы предоставляет ассоциация :has_many. (Я знаю, что :has_many должен предоставить, но хочу проверить это.)

Ответ 1

Ниже перечислены методы, которые класс пользователя имеет, что базовый класс объекта не имеет...

>> 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 имеет не в базовом классе 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 отношений, определенных в классе User, являются not в результатах вызова methods.

Добавлено Обратите внимание: has_many не добавляет методы напрямую. Вместо этого механизм ActiveRecord использует методы Ruby method_missing и responds_to для обработки вызовов метода "на лету". В результате методы не указаны в результатах метода methods.

Ответ 2

Модуль # 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

Ответ 3

Вы можете сделать

current_user.methods

Для лучшего перечисления

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"

Ответ 4

Как насчет одного из них?

object.methods.sort
Class.methods.sort

Ответ 5

Предположим, что пользователь has_many Сообщений:

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

Ответ 6

Извлечь ответ @clyfe. Вы можете получить список ваших методов экземпляра, используя следующий код (при условии, что у вас есть класс объектов с именем "Parser" ):

Parser.new.methods - Object.new.methods

Ответ 7

Если вы ищете список методов, которые отвечают экземпляром (в вашем случае @current_user). Согласно документации ruby ​​methods

Возвращает список имен общедоступных и защищенных методов obj. Это будет включать все методы, доступные для предков obj. Если необязательный параметр - false, он возвращает массив объектов obj открытых и защищенных одноэлементных методах, массив не будет включать методы в модулях, включенных в 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.