Как вы перечисляете доступные в данный момент объекты в текущей области видимости в ruby?

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

  •  04-07-2019
  •  | 
  •  

Вопрос

Я новичок в ruby и играю с IRB.

Я обнаружил, что могу перечислить методы объекта, используя метод ".methods", и этот self.methods вроде как дает мне то, что я хочу (аналогично директории Python (встроенные элементы)?), но как я могу найти методы библиотеки / модуля, которые я загрузил через include и 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>

Я привык к python, где я использую функцию dir() для выполнения того же самого:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>>
Это было полезно?

Решение

Объектное пространство.each_object это может быть то, что вы ищете.

Чтобы получить список включенных модулей, вы могли бы использовать Module.включенные_модули.

Вы также можете проверить, реагирует ли объект на метод в каждом конкретном случае, используя object.response_to?.

Другие советы

Я не совсем уверен в том, что вы подразумеваете под "текущими объектами".Вы можете выполнять итерации по объектному пространству, как уже упоминалось.Но вот несколько других методов.

local_variables
instance_variables
global_variables

class_variables
constants

Есть один попавшийся.Они должны вызываться в нужных областях.Таким образом, прямо в IRB, или в экземпляре объекта, или в области видимости класса (так везде, в принципе) вы можете вызвать первые 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", ...]

Но что, если вы хотите, чтобы ваша программа действительно оценивала их, не требуя от вас многократного ввода?Хитрость заключается в оценке.

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

Последние 2 из 5, упомянутых в начале, должны быть оценены на уровне модуля (класс является потомком модуля, так что это работает).

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"

Вот еще несколько приемов, которые можно изучить в разных направлениях

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

Тот самый dir() метод заключается в не имеет четкого определения...

Примечание: Потому что dir() поставляется в первую очередь для удобства использования в интерактивном приглашении, оно пытается предоставить интересный набор имен больше, чем пытается предоставить строго или последовательно определенный набор имен и его подробное поведение может меняться в разных выпусках.

...но мы можем создать близкое приближение в Ruby.Давайте создадим метод, который вернет отсортированный список всех методов, добавленных в нашу область видимости включенными модулями.Мы можем получить список модулей, которые были включены, используя included_modules способ.

Нравится dir(), мы хотим игнорировать методы "по умолчанию" (например print), и мы также хотим сосредоточиться на "интересном" наборе имен.Итак, мы будем игнорировать методы в Kernel, и мы будем возвращать только методы, которые были определены непосредственно в модулях, игнорируя унаследованные методы.Мы можем сделать это позже, передав false в methods() способ.Собрав все это вместе, мы получаем...

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

Вы можете передать ему класс, объект или ничего (по умолчанию используется текущая область видимости).Давайте попробуем это сделать...

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() также включает локально определенные переменные, и это очень просто.Просто позвони...

local_variables

...к сожалению, мы не можем просто добавить local_variables позвоните в included_methods потому что это дало бы нам переменные, которые являются локальными для included_methods метод, и это было бы не очень полезно.Итак, если вы хотите, чтобы локальные переменные были включены в included_methods, просто вызовите ...

 (included_methods + local_variables).sort

Я написал для этого жемчужину:

$ 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

Я работаю над улучшением параметров передачи и настроек по умолчанию, но пока я бы посоветовал вам добавить следующее в ваш файл .irbrc:

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

Это позволяет использовать цвета и скрывает методы, которые есть у каждого объекта, поскольку они обычно вас не интересуют.

О чем:

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

Здесь перечислены доступные для меня классы.Я не специалист по ruby, и меня подбросили к консоли ruby, не имея ни малейшего представления о том, какие классы были под рукой.Этот лайнер был только началом.

Для доступа ко всем экземплярам объектов в ruby вы используете ObjectSpace

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

Однако это считается медленным (даже для ruby) и может быть недоступно в некоторых интерпретаторах (напримерJRuby может отключить ObjectSpace, поскольку это намного быстрее, полагаясь на jvm для gc, без необходимости отслеживать этот материал в JRuby).

Вы можете передавать сообщения .methods в библиотеку / модуль еще до его загрузки, чтобы просмотреть все доступные методы.Делая self.methods просто возвращает все методы, которые содержит Object object.Вы можете убедиться в этом, выполнив self.class.Итак, предположим, вы хотите увидеть все методы в файловом модуле.Вы просто делаете File.methods и вы получите список всех методов, которые существуют в Файловом модуле.Возможно, это не то, чего вы хотите, но это должно быть в какой-то степени полезно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top