web-dev-qa-db-fra.com

Comment lister toutes les méthodes pour un objet en Ruby?

Comment lister toutes les méthodes auxquelles un objet particulier a accès?

J'ai un @current_user objet, défini dans le contrôleur d’application:

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

Et je veux voir les méthodes dont je dispose dans le fichier de vue. Plus précisément, je veux voir quelles méthodes un :has_many association fournit. (Je sais ce que :has_manydevrait fournir, mais je veux vérifier.)

98
Dirk

Ce qui suit va lister les méthodes de la classe User que la classe Object de base n'a pas ...

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

Notez que methods est une méthode pour les classes et pour les instances de classe.

Voici les méthodes de ma classe User qui ne figurent pas dans la classe de base 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.

Notez que les méthodes créées à la suite des (nombreuses) relations has_many définies dans la classe User sont not dans les résultats de l'appel methods.

Ajouté Notez que has_many n'ajoute pas de méthodes directement. Au lieu de cela, la machine ActiveRecord utilise le Ruby method_missing et responds_to techniques pour gérer les appels de méthode à la volée. Par conséquent, les méthodes ne sont pas répertoriées dans le résultat de la méthode methods.

184
Larry K

Module # instance_methods

Renvoie un tableau contenant les noms des méthodes d'instance publique et protégée dans le récepteur. Pour un module, ce sont les méthodes publiques et protégées; pour une classe, ce sont les méthodes d'instance (pas de singleton). Sans argument ou avec un argument faux, les méthodes d’instance dans mod sont renvoyées, sinon les méthodes des superclasses mod et mod sont renvoyées.

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
9
clyfe

Ou simplement User.methods(false) pour ne renvoyer que les méthodes définies dans cette classe.

5
Ruto Collins

Tu peux faire

current_user.methods

Pour une meilleure inscription

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

Qu'en est-il de l'un d'entre eux?

object.methods.sort
Class.methods.sort
3
Michael Frederick

Si vous êtes à la recherche d'une liste de méthodes qui répondent par une instance (dans votre cas, @ utilisateur_current). Selon Ruby documentation méthodes

Retourne une liste des noms des méthodes publiques et protégées de obj. Cela inclura toutes les méthodes accessibles dans les ancêtres d'obj. Si le paramètre facultatif a la valeur false, il retourne un tableau des méthodes singleton publiques et protégées de obj. Le tableau n'inclura pas de méthodes dans les modules inclus dans 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.

Vous pouvez également vérifier qu'une méthode est appelable sur un objet ou non ?.

@current_user.respond_to?:your_method_name

Si vous ne souhaitez pas utiliser les méthodes de la classe parent, vous devez simplement en soustraire les méthodes de la classe parent.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
1

Suppose que l'utilisateur has_many Posts:

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

Pour expliquer la réponse de @ clyfe. Vous pouvez obtenir une liste de vos méthodes d'instance à l'aide du code suivant (en supposant que vous ayez une classe d'objet nommée "analyseur"):

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