¿Cómo enumerar todos los métodos para un objeto en Ruby?

112

¿Cómo enumero todos los métodos a los que tiene acceso un objeto en particular?

Tengo un @current_userobjeto, definido en el controlador de la aplicación:

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

Y quiero ver qué métodos tengo disponibles en el archivo de vista. Específicamente, quiero ver qué métodos :has_manyproporciona una asociación. (Sé lo que :has_many debería proporcionar, pero quiero comprobarlo).

Puñal
fuente
Para aclarar, ¿desea que los métodos se puedan llamar @current_user?
Andrew Marshall
@Dirk, ¡bienvenido a stackoverflow! Recuerde "comprobar" la respuesta que mejor responda a su pregunta. También vota cualquier respuesta, a cualquier pregunta, que te resulte útil / útil.
Larry K

Respuestas:

210

A continuación, se enumeran los métodos que tiene la clase de usuario que la clase de objeto base no tiene ...

>> 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", ...

Tenga en cuenta que methodses un método para clases y para instancias de clase.

Estos son los métodos que tiene mi clase de usuario que no están en la clase base de 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.

Tenga en cuenta que los métodos creados como resultado de las (muchas) relaciones has_many definidas en la clase Usuario no están en los resultados de la methodsllamada.

Agregado Tenga en cuenta que: has_many no agrega métodos directamente. En cambio, la maquinaria ActiveRecord utiliza Ruby method_missingy responds_totécnicas para manejar llamadas a métodos sobre la marcha. Como resultado, los métodos no se enumeran en el methodsresultado del método.

Larry K
fuente
2
Aunque eso puede no estar completo, ya que algunos métodos solo se crean cuando se llama a method_missing (por ejemplo, buscadores dinámicos)
Frederick Cheung
si intento responds_to? Recibo un error de falta de método. Estoy ejecutando esto dentro de application.html.erb
Dirk
@Dirk: tal vez el método no esté presente ... Le sugiero que presente una nueva pregunta donde muestre cuáles son sus definiciones de clase AR y luego pregunte sobre los métodos específicos que cree que: has_many debería proporcionar. ¿También tiene la coincidencia: pertenece_a? Las reglas de pluralización y capitalización de Rails para AR han llevado a muchos por mal camino ...
Larry K
@Larry. Gracias, puedo obtener una lista con .to_yaml. Se ve así: --- -: bocetos -: sketch_ids -: bocetos = -: sketch_ids = -: before_add_for_sketches -: before_add_for_sketches? <muchos omitidos> ........ ¿cómo accedo a esos métodos? (señalándome la documentación también apreciada :)
Dirk
Los documentos de has_many muestran muchos de los métodos que se agregan. Otros son nuevos para versiones posteriores de Rails. Estos incluyen "before_add_for", etc. Son "devoluciones de llamada de asociación"; consulte esa parte de este documento
Larry K
9

Módulo # instance_methods

Devuelve una matriz que contiene los nombres de los métodos de instancia pública y protegida en el receptor. Para un módulo, estos son los métodos públicos y protegidos; para una clase, son los métodos de instancia (no singleton). Sin argumento, o con un argumento falso, se devuelven los métodos de instancia en mod, de lo contrario se devuelven los métodos en mod y las superclases de 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
clyfe
fuente
6

O simplemente User.methods(false)para devolver solo los métodos definidos dentro de esa clase.

Ruto Collins
fuente
4

Tu puedes hacer

current_user.methods

Para una mejor lista

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"
Andreas Lyngstad
fuente
3

¿Y uno de estos?

object.methods.sort
Class.methods.sort
Michael Frederick
fuente
1

Supongamos que el usuario tiene_many publicaciones:

u = User.first
u.posts.methods
u.posts.methods - Object.methods
Marek Příhoda
fuente
1

Para exponer la respuesta de @ clyfe. Puede obtener una lista de sus métodos de instancia utilizando el siguiente código (asumiendo que tiene una clase de objeto llamada "Analizador"):

Parser.new.methods - Object.new.methods
Jared Menard
fuente
1

Si está buscando una lista de métodos que responden por una instancia (en su caso, @current_user). Según los métodos de documentación ruby

Devuelve una lista de los nombres de los métodos públicos y protegidos de obj. Esto incluirá todos los métodos accesibles en los antepasados ​​de obj. Si el parámetro opcional es falso, devuelve una matriz de métodos singleton públicos y protegidos de obj, la matriz no incluirá métodos en los módulos incluidos en 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.

Alternativamente, también puede verificar que un método sea invocable en un objeto o no.

@current_user.respond_to?:your_method_name

Si no desea métodos de la clase principal, simplemente reste los métodos de la clase principal.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Mukesh Kumar Gupta
fuente