Я нашел интересную, но необъяснимую альтернативу принятому ответу. Код явно работает в 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)
использует объект #метод для выполнения поиска метода и возврата замыкания.
Foo.method(:const_get).call :Bar
— это замыкание, которое возвращает квалифицированный путь к константе внутри класса.
&Foo
кажется какой-то особой лямбдой . Документы говорят:
The & argument preserves the tricks if a Proc object is given by & argument.
Я не уверен, что полностью понимаю, что это значит в данном конкретном контексте. Почему прок? Какие "хитрости" и зачем они тут нужны?
grep(Class)
работает со значением#map метод , но его особенности не очевидны.
Почему эта конструкция карты #возвращает собираемый массив вместо перечислителя?
Foo.constants.map(&Foo.method(:const_get)).class
=> Array
Как на самом деле работает поиск для класса с именем Class и почему здесь необходима именно эта конструкция?
[Foo::Bar].grep Class
=> [Foo::Bar]
Я действительно хотел бы понять эту идиому во всей ее полноте. Может ли кто-нибудь заполнить пробелы здесь и объяснить, как все части сочетаются друг с другом?