Recherche…


Voir les méthodes d'un objet

Inspection d'un objet

Vous pouvez trouver les méthodes publiques auxquelles un objet peut répondre en utilisant les methods ou les methods public_methods , qui renvoient un tableau de symboles:

class Foo
  def bar; 42; end
end
f = Foo.new
def f.yay; 17; end
p f.methods.sort
#=> [:!, :!=, :!~, :<=>, :==, :===, :=~, :__id__, :__send__, :bar, :class, :clone,
#=>  :define_singleton_method, :display, :dup, :enum_for, :eql?, :equal?, :extend,
#=>  :freeze, :frozen?, :hash, :inspect, :instance_eval, :instance_exec,
#=>  :instance_of?, :instance_variable_defined?, :instance_variable_get,
#=>  :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, 
#=>  :method, :methods, :nil?, :object_id, :private_methods, :protected_methods,
#=>  :public_method, :public_methods, :public_send, :remove_instance_variable,
#=>  :respond_to?, :send, :singleton_class, :singleton_method, :singleton_methods,
#=>  :taint, :tainted?, :tap, :to_enum, :to_s, :trust, :untaint, :untrust,
#=>  :untrusted?, :yay]

Pour une liste plus ciblée, vous pouvez supprimer des méthodes communes à tous les objets, par exemple

p (f.methods - Object.methods).sort
#=> [:bar,:yay]

Vous pouvez également transmettre false aux methods ou public_methods :

p f.methods(false) # public and protected singleton methods of `f`
#=> [:yay]

p f.public_methods(false)
#=> [:yay, :bar]

Vous pouvez trouver les méthodes privées et protégées d'un objet en utilisant private_methods et protected_methods :

p f.private_methods.sort
#=> [:Array, :Complex, :DelegateClass, :Float, :Hash, :Integer, :Rational, :String,
#=>  :__callee__, :__dir__, :__method__, :`, :abort, :at_exit, :autoload, :autoload?,
#=>  :binding, :block_given?, :caller, :caller_locations, :catch,
#=>  :default_src_encoding, :eval, :exec, :exit, :exit!, :fail, :fork, :format, :gem,
#=>  :gem_original_require, :gets, :global_variables, :initialize, :initialize_clone,
#=>  :initialize_copy, :initialize_dup, :irb_binding, :iterator?, :lambda, :load,
#=>  :local_variables, :loop, :method_missing, :open, :p, :print, :printf, :proc,
#=>  :putc, :puts, :raise, :rand, :readline, :readlines, :require, :require_relative,
#=>  :respond_to_missing?, :select, :set_trace_func, :singleton_method_added,
#=>  :singleton_method_removed, :singleton_method_undefined, :sleep, :spawn,
#=>  :sprintf, :srand, :syscall, :system, :test, :throw, :trace_var, :trap,
#=>  :untrace_var, :warn]

p f.protected_methods
#=> []

Comme avec les methods et public_methods , vous pouvez transmettre false à private_methods et protected_methods pour supprimer les méthodes héritées.

Inspection d'une classe ou d'un module

Outre les methods , public_methods , protected_methods et private_methods , classes et modules exposent instance_methods , public_instance_methods , protected_instance_methods et private_instance_methods pour déterminer les méthodes exposées pour les objets qui héritent de la classe ou du module. Comme ci-dessus, vous pouvez transmettre false à ces méthodes pour exclure les méthodes héritées:

p Foo.instance_methods.sort
#=> [:!, :!=, :!~, :<=>, :==, :===, :=~, :__id__, :__send__, :bar, :class,
#=>  :clone, :define_singleton_method, :display, :dup, :enum_for, :eql?,
#=>  :equal?, :extend, :freeze, :frozen?, :hash, :inspect, :instance_eval,
#=>  :instance_exec, :instance_of?, :instance_variable_defined?,
#=>  :instance_variable_get, :instance_variable_set, :instance_variables,
#=>  :is_a?, :itself, :kind_of?, :method, :methods, :nil?, :object_id,
#=>  :private_methods, :protected_methods, :public_method, :public_methods,
#=>  :public_send, :remove_instance_variable, :respond_to?, :send,
#=>  :singleton_class, :singleton_method, :singleton_methods, :taint,
#=>  :tainted?, :tap, :to_enum, :to_s, :trust, :untaint, :untrust, :untrusted?]

p Foo.instance_methods(false)
#=> [:bar]

Enfin, si vous oubliez les noms de la plupart d'entre eux à l'avenir, vous pouvez trouver toutes ces méthodes en utilisant des methods :

p f.methods.grep(/methods/)
#=> [:private_methods, :methods, :protected_methods, :public_methods,
#=>  :singleton_methods]

p Foo.methods.grep(/methods/)
#=> [:public_instance_methods, :instance_methods, :private_instance_methods,
#=>  :protected_instance_methods, :private_methods, :methods,
#=>  :protected_methods, :public_methods, :singleton_methods]

Afficher les variables d'instance d'un objet

Il est possible d'interroger un objet sur ses variables d' instance_variables utilisant instance_variables , instance_variable_defined? , et instance_variable_get , et modifiez-les en utilisant instance_variable_set et remove_instance_variable :

class Foo
  attr_reader :bar
  def initialize
    @bar = 42
  end
end
f = Foo.new
f.instance_variables                #=> [:@bar]
f.instance_variable_defined?(:@baz) #=> false
f.instance_variable_defined?(:@bar) #=> true
f.instance_variable_get(:@bar)      #=> 42
f.instance_variable_set(:@bar, 17)   #=> 17
f.bar                               #=> 17
f.remove_instance_variable(:@bar)   #=> 17
f.bar                               #=> nil
f.instance_variables                #=> []

Les noms des variables d'instance incluent le symbole @ . Vous obtiendrez une erreur si vous l'omettez:

f.instance_variable_defined?(:jim)
#=> NameError: `jim' is not allowed as an instance variable name

Afficher les variables globales et locales

Le Kernel expose des méthodes pour obtenir la liste des global_variables et des local_variables :

cats  = 42
$demo = "in progress"
p global_variables.sort
#=> [:$!, :$", :$$, :$&, :$', :$*, :$+, :$,, :$-0, :$-F, :$-I, :$-K, :$-W, :$-a,
#=>  :$-d, :$-i, :$-l, :$-p, :$-v, :$-w, :$., :$/, :$0, :$1, :$2, :$3, :$4, :$5,
#=>  :$6, :$7, :$8, :$9, :$:, :$;, :$<, :$=, :$>, :$?, :$@, :$DEBUG, :$FILENAME,
#=>  :$KCODE, :$LOADED_FEATURES, :$LOAD_PATH, :$PROGRAM_NAME, :$SAFE, :$VERBOSE,
#=>  :$\, :$_, :$`, :$binding, :$demo, :$stderr, :$stdin, :$stdout, :$~]

p local_variables
#=> [:cats]

Contrairement aux variables d'instance, il n'existe aucune méthode spécifique pour obtenir, définir ou supprimer des variables globales ou locales. Rechercher une telle fonctionnalité est généralement un signe que votre code doit être réécrit pour utiliser un hachage pour stocker les valeurs. Cependant, si vous devez modifier des variables globales ou locales par nom, vous pouvez utiliser eval avec une chaîne:

var = "$demo"
eval(var)           #=> "in progress"
eval("#{var} = 17")
p $demo             #=> 17

Par défaut, eval évaluera vos variables dans la portée actuelle. Pour évaluer les variables locales dans une portée différente, vous devez capturer la liaison où les variables locales existent.

def local_variable_get(name, bound=nil)
  foo = :inside
  eval(name,bound)
end

def test_1
  foo = :outside
  p local_variable_get("foo")
end

def test_2
  foo = :outside
  p local_variable_get("foo",binding)
end
  
test_1 #=> :inside
test_2 #=> :outside

Dans ce qui précède, test_1 n'a pas passé une liaison aux local_variable_get , et donc le eval a été exécuté dans le cadre de cette méthode, où une variable locale nommée foo a été réglée à :inside l' :inside .

Afficher les variables de classe

Les classes et les modules ont les mêmes méthodes pour l'introspection des variables d'instance que tout autre objet. La classe et les modules ont également des méthodes similaires pour interroger les variables de classe ( @@these_things ):

p Module.methods.grep(/class_variable/)
#=> [:class_variables, :class_variable_get, :remove_class_variable,
#=>  :class_variable_defined?, :class_variable_set]

class Foo
  @@instances = 0
  def initialize
    @@instances += 1
  end
end

class Bar < Foo; end

5.times{ Foo.new }
3.times{ Bar.new }
p Foo.class_variables                   #=> [:@@instances]
p Bar.class_variables                   #=> [:@@instances]
p Foo.class_variable_get(:@@instances)  #=> 8
p Bar.class_variable_get(:@@instances)  #=> 8

Semblable aux variables d'instance, le nom des variables de classe doit commencer par @@ , ou vous obtiendrez une erreur:

p Bar.class_variable_defined?( :instances )
#=> NameError: `instances' is not allowed as a class variable name


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow