ruby - 内省(introspection)模块类时 "#map(&proc)"习惯用法如何工作?

标签 ruby constants introspection idioms proc

呈现成语

我找到了一个 interesting but unexplained alternative到一个公认的答案。该代码在 REPL 中显然有效。例如:

module Foo
  class Bar
    def baz
    end
  end
end
Foo.constants.map(&Foo.method(:const_get)).grep(Class)
=> [Foo::Bar]

但是,我并不完全理解这里使用的成语。特别是,我不明白 &Foo 的用法,它似乎是某种闭包,或者 #grep 的这种特定调用如何对结果进行操作。

解析成语

到目前为止,我已经能够解析其中的点点滴滴,但我并没有真正看到它们是如何组合在一起的。以下是我认为对示例代码的理解。

  1. Foo.constants 以符号形式返回模块常量数组。

  2. 方法(:const_get) 使用Object#method执行方法查找并返回闭包。

  3. Foo.method(:const_get).call :Bar 是一个闭包,它返回类中常量的限定路径。

  4. &Foo 好像是some sort of special lambda .文档说:

    The & argument preserves the tricks if a Proc object is given by & argument.

    我也不确定我是否完全理解在这种特定情况下这意味着什么。为什么是过程?什么“技巧”,为什么在这里需要它们?

  5. grep(Class)#map method 的值进行操作, 但其特征并不明显。

    • 为什么这个 #map 构造返回一个可 greppable 数组而不是枚举器?

      Foo.constants.map(&Foo.method(:const_get)).class
      => Array
      
    • grep 查找名为 Class 的类实际上是如何工作的,为什么这里需要这种特殊构造?

      [Foo::Bar].grep Class
      => [Foo::Bar]
      

重述问题

我真的很想完整地理解这个成语。任何人都可以填补这里的空白,并解释所有部分是如何组合在一起的吗?

最佳答案

&Foo.method(:const_get)Foo 对象的 const_get 方法。这是另一个例子:

m = 1.method(:+)
#=> #<Method: Fixnum#+>
m.call(1)
#=> 2
(1..3).map(&m)
#=> [2, 3, 4]

所以最后这只是一个pointfree Foo.constants.map { |c| 的表达方式Foo.const_get(c) }grep 使用 === 来选择元素,因此它只会获取引用类的常量,而不是其他值。这可以通过向 Foo 添加另一个常量来验证,例如Baz = 1,不会得到 grepped。

如果您还有其他问题,请将其添加为评论,我会尽力澄清。

关于ruby - 内省(introspection)模块类时 "#map(&proc)"习惯用法如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11505835/

相关文章:

python - 如何在 python 中获取变量的字符串表示形式?

ruby - 在 rspec 中测试多步骤工作流程

ruby - 在 Ruby 中将值设置为数字范围

ruby - 如何在 Ruby 中对 PDF 文档进行数字签名?

java - JTabbedPane:避免在堆叠/Nimbus 时自动重新排序选项卡

java - 如何通过类在java中获取常量

python - 使用内省(introspection)来查找对象的方法,然后进行过滤

Python/Ruby 作为移动操作系统

c++ - 基于范围的隐式添加 `const` 限定符?

javascript - 如何查找函数中定义的变量