如何在 ruby​​ 中列出当前范围内当前可用的对象?

发布于 2024-07-08 07:08:34 字数 1824 浏览 7 评论 0原文

我是 ruby​​ 新手,正在使用 IRB。

我发现我可以使用“.methods”方法列出对象的方法,并且 self.methods 可以给我我想要的东西(类似于 Python 的 dir(builtins)?),但是如何我可以找到通过 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__']
>>>

I'm new to ruby and I'm playing around with the IRB.

I found that I can list methods of an object using the ".methods" method, and that self.methods sort of give me what I want (similar to Python's dir(builtins)?), but how can I find the methods of a library/module I've loaded via include and 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>

I'm used to python, where I use the dir() function to accomplish the same thing:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

榕城若虚 2024-07-15 07:08:34

我不完全确定“当前对象”是什么意思。 正如已经提到的,您可以迭代 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", "$\"", "$", "
lt;", "$_", ...]
$"                  #=> ["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", ...]

但是,嗯,如果您希望程序实际评估它们而不需要多次键入它们,该怎么办? 诀窍是评估。

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

开头提到的 5 个中的最后 2 个必须在模块级别进行评估(类是模块的后代,因此可以工作)。

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

I'm not entirely sure of what you mean by the 'current objects'. You can iterate over ObjectSpace, as has been mentioned already. But here are a few other methods.

local_variables
instance_variables
global_variables

class_variables
constants

There's one gotcha. They must be called at the right scopes. So right in IRB, or in an object instance or at class scope (so everywhere, basically) you can call the first 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", "$\"", "$", "
lt;", "$_", ...]
$"                  #=> ["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", ...]

But umm, what if you want your program to actually evaluate them without needing you to type them manyally? The trick is eval.

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

The last 2 of the 5 mentioned at the beginning must be evaluated at the module level (a class is a descendant of a module, so that works).

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"

Here's are a few more tricks to explore in different 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...", ...]
放血 2024-07-15 07:08:34

ObjectSpace.each_object 可能就是您正在寻找的为了。

要获取包含的模块列表,您可以使用 Module.included_modules

您还可以使用 object.respond_to?

ObjectSpace.each_object could be what you are looking for.

To get a list of included modules you could use Module.included_modules.

You can also check if an object responds to a method on a case-by-case basis using object.respond_to?.

鹿港小镇 2024-07-15 07:08:34

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

The dir() method is not clearly defined...

Note: Because dir() is supplied
primarily as a convenience for use at
an interactive prompt, it tries to
supply an interesting set of names
more than it tries to supply a
rigorously or consistently defined set
of names, and its detailed behavior
may change across releases.

...but we can create a close approximation in Ruby. Let's make a method that will return a sorted list of all methods added to our scope by included modules. We can get a list of the modules that have been included by using the included_modules method.

Like dir(), we want to ignore the "default" methods (like print), and we also want to focus on the "interesting" set of names. So, we will ignore methods in Kernel, and we will only return methods that were defined directly in the modules, ignoring inherited methods. We can accomplish the later by passing false into the methods() method. Putting it all together we get...

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

You can pass it a class, an object, or nothing (it defaults to the current scope). Let's try it out...

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() also includes locally defined variables, and that's an easy one. Just call...

local_variables

...unfortunately, we can't just add the local_variables call to included_methods because it would give us the variables that are local to the included_methods method, and that wouldn't be very useful. So, if you want local variables included with the included_methods, just call...

 (included_methods + local_variables).sort
記憶穿過時間隧道 2024-07-15 07:08:34

我为此编写了一个 gem:

$ 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
}

这会启用颜色并隐藏每个对象具有的方法,因为您通常对这些不感兴趣。

I wrote a gem for that:

$ 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

I am working on an improvement of passing options and settings defaults, but for now I would suggest you add the following to your .irbrc file:

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

This enables colours and hides the methods that every object has, since you're usually not interested in those.

删除会话 2024-07-15 07:08:34

怎么样:

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

列出了我可以选择的课程。 我不是红宝石专家,我被丢在红宝石控制台上,不知道手头有什么课程。 那艘班轮是一个开始。

What about:

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

That lists available classes for me. I am not ruby expert and I was being dropped at a ruby console with no idea of what classes were at hand. That one liner was a start.

泛滥成性 2024-07-15 07:08:34

要访问 ruby​​ 中的所有对象实例,请使用 ObjectSpace

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

但是,这被认为很慢(即使对于 ruby​​),并且在某些解释器中可能无法启用(例如 jRuby)可以禁用 ObjectSpace,因为它依靠 jvm 进行 gc 更快,而无需在 jRuby 中跟踪这些东西)。

To access all object instances in ruby you use ObjectSpace

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

However, this is considered slow (even for ruby), and may not be enabled in some interpreters (e.g. jRuby can disable ObjectSpace as it is much faster relying in the jvm for gc without needing to track this stuff in jRuby).

贪恋 2024-07-15 07:08:34

您甚至可以在加载之前将 .methods 消息传递到库/模块,以查看所有可用的方法。 执行 self.methods 只会返回 Object 对象包含的所有方法。 您可以通过执行 self.class 来看到这一点。 假设您想查看 File 模块中的所有方法。 您只需执行 File.methods 即可获得 File 模块中存在的所有方法的列表。 这也许不是您想要的,但它应该有所帮助。

You can pass the .methods messages to the library/module even before loading it, to see all the available methods. Doing self.methods just returns all the methods that the Object object contains. You can see this by doing self.class. So let's say you want to see all the methods in the File module. You simply do File.methods and you'll get a list of all the methods that exist in the File module. This, perhaps, isn't what you want, but it should be somewhat helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文