variable una tipos listas lista elemento declarar crear constantes como arreglo alcance agregar ruby introspection irb

una - ruby listas



¿Cómo se enumeran los objetos actualmente disponibles en el alcance actual en ruby? (7)

Soy nuevo en ruby ​​y estoy jugando con el IRB.

Descubrí que puedo enumerar los métodos de un objeto utilizando el método ".methods", y que el método self.methods me da lo que quiero (similar al dir de Python ( builtins )?), Pero ¿cómo puedo encontrar los métodos de un biblioteca / módulo que he cargado mediante include y require?

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>

Estoy acostumbrado a Python, donde uso la función dir () para lograr lo mismo:

>>> dir() [''__builtins__'', ''__doc__'', ''__name__'', ''__package__''] >>>


Escribí una joya para eso:

$ 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

Estoy trabajando en una mejora de las opciones de paso y configuración predeterminada, pero por ahora sugeriría que agregue lo siguiente a su archivo .irbrc:

require ''method_info'' MethodInfo::OptionHandler.default_options = { :ancestors_to_exclude => [Object], :enable_colors => true }

Esto habilita colores y oculta los métodos que tiene cada objeto, ya que generalmente no está interesado en ellos.


Para acceder a todas las instancias de objeto en ruby, usa ObjectSpace

http://www.ruby-doc.org/core-1.8.7/classes/ObjectSpace.html#M000928

Sin embargo, esto se considera lento (incluso para ruby) y puede no estar habilitado en algunos intérpretes (p. Ej. JRuby puede deshabilitar ObjectSpace ya que es mucho más rápido confiar en el jvm para gc sin necesidad de seguir esto en jRuby).


Puede pasar los mensajes .methods a la biblioteca / módulo incluso antes de cargarlo, para ver todos los métodos disponibles. Hacer self.methods solo devuelve todos los métodos que contiene el objeto Object. Puedes ver esto haciendo self.class . Digamos que desea ver todos los métodos en el módulo Archivo. Simplemente haga File.methods y obtendrá una lista de todos los métodos que existen en el módulo File. Esto, quizás, no es lo que quieres, pero debería ser de alguna ayuda.



El método dir() no está claramente definido ...

Nota: Debido a que dir() se proporciona principalmente para su uso en un aviso interactivo, trata de proporcionar un conjunto interesante de nombres más de lo que intenta proporcionar un conjunto de nombres riguroso o consistentemente definido, y su comportamiento detallado puede cambiar a través de lanzamientos.

... pero podemos crear una aproximación cercana en Ruby. Hagamos un método que devuelva una lista ordenada de todos los métodos agregados a nuestro alcance por los módulos incluidos. Podemos obtener una lista de los módulos que se han incluido utilizando el método included_modules .

Al igual que dir() , queremos ignorar los métodos "predeterminados" (como print ), y también queremos enfocarnos en el conjunto de nombres "interesantes". Por lo tanto, ignoraremos los métodos en Kernel , y solo devolveremos los métodos que se definieron directamente en los módulos, ignorando los métodos heredados. Podemos lograr lo último pasando false al método methods() . Poniendo todo junto, obtenemos ...

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

Puede pasarle una clase, un objeto o nada (su valor predeterminado es el alcance actual). Probémoslo ...

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"]

dir() también incluye variables definidas localmente, y eso es fácil. Solo llama...

local_variables

... desafortunadamente, no podemos simplemente agregar la llamada local_variables los local_variables porque nos daría las variables que son locales para el método de local_variables , y eso no sería muy útil. Por lo tanto, si quieres incluir variables locales con los methods_methods, solo llama ...

(included_methods + local_variables).sort


No estoy del todo seguro de lo que quiere decir con los "objetos actuales". Puede iterar sobre ObjectSpace, como ya se ha mencionado. Pero aquí hay algunos otros métodos.

local_variables instance_variables global_variables class_variables constants

Hay una gotcha. Deben ser llamados en los ámbitos correctos. Así que en IRB, o en una instancia de objeto o en el alcance de clase (así que en todas partes, básicamente) puede llamar a los primeros 3.

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", ...]

Pero umm, ¿y si quieres que tu programa los evalúe realmente sin necesidad de que los digite mucho? El truco es eval.

eval "@inst_var" #=> 42 global_variables.each do |v| puts eval(v) end

Los últimos 2 de los 5 mencionados al principio deben evaluarse a nivel de módulo (una clase es un descendiente de un módulo, por lo que funciona).

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"

Aquí hay algunos trucos más para explorar en diferentes direcciones

"".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...", ...]


Qué pasa:

Object.constants.select{|x| eval(x.to_s).class == Class}

Eso enumera las clases disponibles para mí. No soy un experto en rubíes y estaba siendo arrojado a una consola de rubí sin tener idea de qué clases tenían a mano. Ese único trazador de líneas fue un comienzo.