Comment lister toutes les méthodes d'un objet dans Ruby?


113

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

J'ai un @current_userobjet, 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 une :has_manyassociation propose. (Je sais ce que je :has_many dois fournir, mais je veux le vérifier.)


Pour clarifier, vous voulez que les méthodes soient appelables @current_user?
Andrew Marshall

@Dirk, bienvenue dans stackoverflow! N'oubliez pas de «cocher» la réponse qui répond le mieux à votre question. Également pour toute réponse, à toute question, que vous trouvez utile / utile.
Larry K

Réponses:


211

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 qu'il methodss'agit d'une méthode pour les classes et pour les instances de classe.

Voici les méthodes de ma classe User qui ne sont 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 ne figurent pas dans les résultats de lamethods appel.

Ajouté Notez que: has_many n'ajoute pas directement de méthodes. Au lieu de cela, la machine ActiveRecord utilise le Ruby method_missinget des responds_totechniques 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 methodsrésultat de la méthode.


2
Bien que cela puisse ne pas être complet puisque certaines méthodes ne sont créées que lorsque method_missing est appelée (par exemple, les chercheurs dynamiques)
Frederick Cheung

si j'essaye réponds_à? J'obtiens une erreur de méthode manquante.
Dirk

@Dirk - peut-être que la méthode n'est pas présente ... Je vous suggère de déposer une nouvelle question où vous montrez quelles sont vos définitions de classe AR, puis demandez les méthodes spécifiques que vous pensez que has_many devrait fournir. Avez-vous également la correspondance: appartient_to? Les règles de capitalisation et de pluralisation de Rails pour AR ont égaré beaucoup de gens ...
Larry K

@Larry. Merci - Je peux obtenir une liste avec .to_yaml. Cela ressemble à ceci: --- -: croquis -: sketch_ids -: croquis = -: sketch_ids = -: before_add_for_sketches -: before_add_for_sketches? <plusieurs omis> ........ comment accéder à ces méthodes? (me dirigeant vers une documentation appréciée aussi :)
Dirk

La documentation pour: has_many montre de nombreuses méthodes ajoutées. D'autres sont nouveaux pour les versions ultérieures de Rails. Ceux-ci incluent le "before_add_for" etc. Ce sont des "rappels d'association" - voir cette partie de ce document
Larry K

9

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 (et non singleton). Sans argument, ou avec un argument qui est faux, les méthodes d'instance dans mod sont retournées, sinon les méthodes dans les superclasses de mod et de mod sont retourné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

6

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


4

Tu peux faire

current_user.methods

Pour une meilleure liste

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


1

Supposons que l'utilisateur ait de nombreux messages:

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

1

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 "Parser"):

Parser.new.methods - Object.new.methods

1

Si vous recherchez une liste de méthodes qui répondent par une instance (dans votre cas @current_user). Selon les méthodes de documentation ruby

Renvoie 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 est false, il renvoie un tableau des méthodes singleton publiques et protégées d'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 voulez pas de méthodes de classe parente, soustrayez simplement les méthodes de classe parente.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.