イディオムの提示
受け入れられた答えに代わる、興味深いが説明のつかない代替案を見つけました。コードは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
モジュール定数の配列をシンボルとして返します。method(:const_get)
Object#methodを使用してメソッドルックアップを実行し、クロージャを返します。Foo.method(:const_get).call :Bar
クラス内の定数への修飾パスを返すクロージャです。&Foo
ある種の特別なラムダのようです。ドキュメントによると:Procオブジェクトが&引数で指定されている場合、&引数はトリックを保持します。
この特定の文脈でも、それが何を意味するのかを完全に理解しているのかわかりません。なぜProc?どのような「トリック」があり、なぜここで必要なのですか?
grep(Class)
は#mapメソッドの値で動作していますが、その機能は明らかではありません。この#mapコンストラクトが列挙子ではなくgreppable配列を返すのはなぜですか?
Foo.constants.map(&Foo.method(:const_get)).class => Array
Classという名前のクラスのgrepは実際にどのように機能し、なぜここでその特定の構築が必要なのですか?
[Foo::Bar].grep Class => [Foo::Bar]
質問、言い換え
このイディオム全体を本当に理解したいと思います。誰かがここのギャップを埋めて、すべてのピースがどのように組み合わされているかを説明できますか?