Comment listez-vous les objets actuellement disponibles dans la portée actuelle en ruby?

StackOverflow https://stackoverflow.com/questions/228648

  •  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__']
>>>
Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top