呈现成语
我找到了一个 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 的这种特定调用如何对结果进行操作。
解析成语
到目前为止,我已经能够解析其中的点点滴滴,但我并没有真正看到它们是如何组合在一起的。以下是我认为对示例代码的理解。
Foo.constants
以符号形式返回模块常量数组。方法(:const_get)
使用Object#method执行方法查找并返回闭包。Foo.method(:const_get).call :Bar
是一个闭包,它返回类中常量的限定路径。&Foo
好像是some sort of special lambda .文档说:The & argument preserves the tricks if a Proc object is given by & argument.
我也不确定我是否完全理解在这种特定情况下这意味着什么。为什么是过程?什么“技巧”,为什么在这里需要它们?
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
,不会得到 grep
ped。
如果您还有其他问题,请将其添加为评论,我会尽力澄清。
关于ruby - 内省(introspection)模块类时 "#map(&proc)"习惯用法如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11505835/