Подтвердить что ты не робот

Как вы указываете текущие доступные объекты в текущей области в 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__']
>>>
4b9b3361

Ответ 1

ObjectSpace.each_object может быть тем, что вы ищете.

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

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

Ответ 2

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

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

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

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

Ответ 3

Метод 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, и это было бы не очень полезно. Итак, если вы хотите, чтобы локальные переменные включались в include_methods, просто вызывайте...

 (included_methods + local_variables).sort

Ответ 4

Я написал для этого камень:

$ 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 :::
%, &, *, **, +, -, [email protected], /, <, <<, <=, <=>, ==, >, >=, >>, [], ^, 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 :::
[email protected], 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
}

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

Ответ 5

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

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

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

Ответ 6

Как насчет:

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

Это список доступных классов для меня. Я не эксперт по рубину, и меня бросали на рубиновую консоль, не зная, какие классы были под рукой. Этот лайнер был началом.

Ответ 7

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