Tod*_*obs 13 ruby idioms constants introspection proc
我发现了一个有趣但无法解释的替代方案.代码清楚地在REPL中起作用.例如:
module Foo
class Bar
def baz
end
end
end
Foo.constants.map(&Foo.method(:const_get)).grep(Class)
=> [Foo::Bar]
Run Code Online (Sandbox Code Playgroud)
但是,我并不完全理解这里使用的习语.特别是,我不理解使用&Foo,这似乎是某种闭包,或者#grep的这种特定调用如何对结果进行操作.
到目前为止,我已经能够解析这部分内容了,但我并没有真正看到它们是如何组合在一起的.以下是我认为我对示例代码的理解.
Foo.constants 返回模块常量数组作为符号.
method(:const_get)使用Object#方法执行方法查找并返回闭包.
Foo.method(:const_get).call :Bar 是一个闭包,它返回类中常量的限定路径.
&Foo似乎是某种特殊的lambda.文档说:
如果Proc对象由&参数给出,&参数将保留技巧.
我不确定我是否完全理解这在特定背景下的含义.为什么选择Proc?什么"诡计",为什么这里有必要?
grep(Class)正在运行#map方法的值,但其功能并不明显.
为什么这个#map构造返回一个greppable Array而不是Enumerator?
Foo.constants.map(&Foo.method(:const_get)).class
=> Array
Run Code Online (Sandbox Code Playgroud)如何为一个名为Class的类的grepping实际工作,为什么这里需要特定的构造?
[Foo::Bar].grep Class
=> [Foo::Bar]
Run Code Online (Sandbox Code Playgroud)我真的很想完全理解这个成语.任何人都可以在这里填补空白,并解释这些部分是如何组合在一起的吗?
&Foo.method(:const_get)是该方法const_get的的Foo对象.这是另一个例子:
m = 1.method(:+)
#=> #<Method: Fixnum#+>
m.call(1)
#=> 2
(1..3).map(&m)
#=> [2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
所以最后这只是一种无拘无束的说法Foo.constants.map { |c| Foo.const_get(c) }.grep用于===选择元素,因此它只会获取引用类的常量,而不是其他值.这可以通过添加另一个常数来验证Foo,例如Baz = 1,哪个不会得到grepped.
如果您还有其他问题,请将其添加为评论,我会尝试澄清它们.