Как работает идиома «#map (&proc )» при анализе классов модулей?

Представление идиомы

Я нашел интересную, но необъяснимую альтернативу принятому ответу. Код явно работает в 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. method(:const_get)использует объект #метод для выполнения поиска метода и возврата замыкания.

  3. Foo.method(:const_get).call :Bar— это замыкание, которое возвращает квалифицированный путь к константе внутри класса.

  4. &Fooкажется какой-то особой лямбдой . Документы говорят:

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

    Я не уверен, что полностью понимаю, что это значит в данном конкретном контексте. Почему прок? Какие "хитрости" и зачем они тут нужны?

  5. grep(Class)работает со значением#map метод , но его особенности не очевидны.

    • Почему эта конструкция карты #возвращает собираемый массив вместо перечислителя?

      Foo.constants.map(&Foo.method(:const_get)).class
      => Array
      
    • Как на самом деле работает поиск для класса с именем Class и почему здесь необходима именно эта конструкция?

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

Вопрос в новой формулировке

Я действительно хотел бы понять эту идиому во всей ее полноте. Может ли кто-нибудь заполнить пробелы здесь и объяснить, как все части сочетаются друг с другом?

13
задан Community 23 May 2017 в 12:34
поделиться