Comment listez-vous les objets actuellement disponibles dans la portée actuelle en ruby?
-
04-07-2019 - |
Question
Je suis nouveau sur Ruby et je joue avec la CISR.
J'ai constaté que je pouvais répertorier les méthodes d'un objet à l'aide de & "; méthodes. &"; Cette méthode me donne ce que je veux (comme le répertoire de Python ( builtins )?), mais comment puis-je trouver les méthodes d'une bibliothèque / d'un module que j'ai chargé via include et besoin?
irb(main):036:0* self.methods
=> ["irb_pop_binding", "inspect", "taguri", "irb_chws", "clone", "irb_pushws", "public_methods", "taguri=", "irb_pwws",
"public", "display", "irb_require", "irb_exit", "instance_variable_defined?", "irb_cb", "equal?", "freeze", "irb_context
", "irb_pop_workspace", "irb_cwb", "irb_jobs", "irb_bindings", "methods", "irb_current_working_workspace", "respond_to?"
, "irb_popb", "irb_cws", "fg", "pushws", "conf", "dup", "cwws", "instance_variables", "source", "cb", "kill", "help", "_
_id__", "method", "eql?", "irb_pwb", "id", "bindings", "send", "singleton_methods", "popb", "irb_kill", "chws", "taint",
"irb_push_binding", "instance_variable_get", "frozen?", "irb_source", "pwws", "private", "instance_of?", "__send__", "i
rb_workspaces", "to_a", "irb_quit", "to_yaml_style", "irb_popws", "irb_change_workspace", "jobs", "type", "install_alias
_method", "irb_push_workspace", "require_gem", "object_id", "instance_eval", "protected_methods", "irb_print_working_wor
kspace", "irb_load", "require", "==", "cws", "===", "irb_pushb", "instance_variable_set", "irb_current_working_binding",
"extend", "kind_of?", "context", "gem", "to_yaml_properties", "quit", "popws", "irb", "to_s", "to_yaml", "irb_fg", "cla
ss", "hash", "private_methods", "=~", "tainted?", "include", "irb_cwws", "irb_change_binding", "irb_help", "untaint", "n
il?", "pushb", "exit", "irb_print_working_binding", "is_a?", "workspaces"]
irb(main):037:0>
Je suis habitué au python, où j'utilise la fonction dir () pour accomplir la même chose:
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>>
La solution
ObjectSpace.each_object pourrait être ce que vous recherchez.
Pour obtenir la liste des modules inclus, vous pouvez utiliser Module.included_modules .
Vous pouvez également vérifier si un objet répond à une méthode cas par cas à l'aide de object.respond_to? .
Autres conseils
Je ne suis pas tout à fait sûr de ce que vous entendez par «objets actuels». Vous pouvez effectuer une itération sur ObjectSpace, comme cela a déjà été mentionné. Mais voici quelques autres méthodes.
local_variables
instance_variables
global_variables
class_variables
constants
Il y en a un. Ils doivent être appelés à la bonne portée. Donc, directement dans IRB, ou dans une instance d'objet ou au niveau de la classe (essentiellement partout), vous pouvez appeler les 3 premiers.
local_variables #=> ["_"]
foo = "bar"
local_variables #=> ["_", "foo"]
# Note: the _ variable in IRB contains the last value evaluated
_ #=> "bar"
instance_variables #=> []
@inst_var = 42
instance_variables #=> ["@inst_var"]
global_variables #=> ["$-d", "$\"", "$$", "$<", "$_", ...]
$" #=> ["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", ...]
Mais, hum, que se passe-t-il si vous voulez que votre programme les évalue réellement sans qu'il soit nécessaire que vous les dactylographiez plusieurs Le truc est eval.
eval "@inst_var" #=> 42
global_variables.each do |v|
puts eval(v)
end
Les 2 derniers des 5 mentionnés au début doivent être évalués au niveau du module (une classe est un descendant d'un module, donc cela fonctionne).
Object.class_variables #=> []
Object.constants #=> ["IO", "Duration", "UNIXserver", "Binding", ...]
class MyClass
A_CONST = 'pshh'
class InnerClass
end
def initialize
@@meh = "class_var"
end
end
MyClass.constants #=> ["A_CONST", "InnerClass"]
MyClass.class_variables #=> []
mc = MyClass.new
MyClass.class_variables #=> ["@@meh"]
MyClass.class_eval "@@meh" #=> "class_var"
Voici quelques astuces supplémentaires à explorer dans différentes directions
"".class #=> String
"".class.ancestors #=> [String, Enumerable, Comparable, ...]
String.ancestors #=> [String, Enumerable, Comparable, ...]
def trace
return caller
end
trace #=> ["(irb):67:in `irb_binding'", "/System/Library/Frameworks/Ruby...", ...]
La dir()
méthode est non clairement définie ...
Remarque: car
included_modules
est fourni. principalement comme une commodité pour une utilisation à une invite interactive, il essaie de fournir un ensemble intéressant de noms plus que d'essayer de fournir un ensemble défini de manière rigoureuse ou cohérente des noms et son comportement détaillé peut changer d'une version à l'autre.
... mais nous pouvons créer une approximation proche en Ruby. Créons une méthode qui retournera une liste triée de toutes les méthodes ajoutées à notre portée par les modules inclus. Nous pouvons obtenir une liste des modules inclus en utilisant la print
méthode.
Comme Kernel
, nous voulons ignorer le " défaut " méthodes (comme false
), et nous souhaitons également nous concentrer sur les & «intéressant»! ensemble de noms. Ainsi, nous ignorerons les méthodes dans methods()
et nous ne renverrons que les méthodes définies directement dans les modules, en ignorant les méthodes héritées. Nous pouvons accomplir cela plus tard en passant local_variables
à la méthode included_methods
. En réunissant tout cela, nous obtenons ...
def included_methods(object=self)
object = object.class if object.class != Class
modules = (object.included_modules-[Kernel])
modules.collect{ |mod| mod.methods(false)}.flatten.sort
end
Vous pouvez lui transmettre une classe, un objet ou rien (la portée par défaut est la portée actuelle). Essayons-le ...
irb(main):006:0> included_methods
=> []
irb(main):007:0> include Math
=> Object
irb(main):008:0> included_methods
=> ["acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "cos", "cosh", "erf", "erfc", "exp", "frexp", "hypot", "ldexp", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh"]
<=> inclut également des variables définies localement, ce qui est simple. Il suffit d'appeler ...
local_variables
... malheureusement, nous ne pouvons pas simplement ajouter l'appel <=> à <=> car il nous donnerait les variables locales à la méthode <=>, ce qui ne serait pas très utile. Donc, si vous voulez que les variables locales soient incluses avec included_methods, appelez simplement ...
(included_methods + local_variables).sort
J'ai écrit un petit bijou pour ça:
$ gem install method_info
$ rvm use 1.8.7 # (1.8.6 works but can be very slow for an object with a lot of methods)
$ irb
> require 'method_info'
> 5.method_info
::: Fixnum :::
%, &, *, **, +, -, -@, /, <, <<, <=, <=>, ==, >, >=, >>, [], ^, abs,
div, divmod, even?, fdiv, id2name, modulo, odd?, power!, quo, rdiv,
rpower, size, to_f, to_s, to_sym, zero?, |, ~
::: Integer :::
ceil, chr, denominator, downto, floor, gcd, gcdlcm, integer?, lcm,
next, numerator, ord, pred, round, succ, taguri, taguri=, times, to_i,
to_int, to_r, to_yaml, truncate, upto
::: Precision :::
prec, prec_f, prec_i
::: Numeric :::
+@, coerce, eql?, nonzero?, pretty_print, pretty_print_cycle,
remainder, singleton_method_added, step
::: Comparable :::
between?
::: Object :::
clone, to_yaml_properties, to_yaml_style, what?
::: MethodInfo::ObjectMethod :::
method_info
::: Kernel :::
===, =~, __clone__, __id__, __send__, class, display, dup, enum_for,
equal?, extend, freeze, frozen?, hash, id, inspect, instance_eval,
instance_exec, instance_of?, instance_variable_defined?,
instance_variable_get, instance_variable_set, instance_variables,
is_a?, kind_of?, method, methods, nil?, object_id, pretty_inspect,
private_methods, protected_methods, public_methods, respond_to?, ri,
send, singleton_methods, taint, tainted?, tap, to_a, to_enum, type,
untaint
=> nil
Je travaille sur une amélioration des options par défaut et des paramètres par défaut, mais pour l'instant, je vous suggère d'ajouter les éléments suivants à votre fichier .irbrc:
require 'method_info'
MethodInfo::OptionHandler.default_options = {
:ancestors_to_exclude => [Object],
:enable_colors => true
}
Ceci active les couleurs et masque les méthodes de chaque objet, car elles ne vous intéressent généralement pas.
Qu'en est-il de:
Object.constants.select{|x| eval(x.to_s).class == Class}
Cela répertorie les classes disponibles pour moi. Je ne suis pas un expert en rubis et je suis tombé sur une console Ruby sans avoir la moindre idée de ce que les classes étaient sous la main. Ce paquebot était un début.
Pour accéder à toutes les instances d'objet dans Ruby, utilisez ObjectSpace
http: //www.ruby-doc .org / core-1.8.7 / classes / ObjectSpace.html # M000928
Cependant, ceci est considéré comme lent (même pour ruby) et peut ne pas être activé par certains interprètes (par exemple, jRuby peut désactiver ObjectSpace car il est beaucoup plus rapide de se fier à jvm pour gc sans avoir à suivre ce genre de choses dans jRuby).
Vous pouvez transmettre les messages .methods à la bibliothèque / module avant même de la charger, pour voir toutes les méthodes disponibles. Faire self.methods
retourne simplement toutes les méthodes contenues dans l’objet Object. Vous pouvez voir cela en faisant self.class
. Supposons donc que vous souhaitiez voir toutes les méthodes dans le module Fichier. Vous faites simplement File.methods
et vous obtiendrez une liste de toutes les méthodes qui existent dans le module Fichier. Ce n’est peut-être pas ce que vous voulez, mais cela devrait vous être utile.