Ruby Language
Introspection
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