Определенный? ключевое слово в Ruby

Обзор определенного? ключевое слово с вариантом использования из исходного кода Ruby ... и совет по оптимизации!

В этой статье мы собираемся изучить следующие темы:

  • ключевое слово defined?
  • defined? в контексте resolv-replace
  • defined? yield vs block_given?

Прежде чем начать

Позвольте мне представить здесь платформу, которая помогла мне изучить большую часть моих знаний о Ruby. Действительно, Pluralsight - потрясающая платформа.

С 50+ курсами, которые охватывают различные темы по Ruby и Ruby on Rails, это лучший способ поднять свои знания на новый уровень!

Попробуйте бесплатно 👇😉



Спасибо за уделенное время!

Определенный? ключевое слово

В Ruby ключевое слово defined? возвращает строку, представляющую тип объекта, переданного в качестве аргумента. Вот исчерпывающий список того, что вы можете передать defined?

Здесь мы видим, что defined? обрабатывает максимум случаев. Но одни случаи более актуальны, чем другие. Например, давайте посмотрим, как библиотека resolv-replace, доступная в стандартной библиотеке Ruby, использует это ключевое слово для обработки действительно сложных случаев.

определенный? в контексте resolv-replace

Эта библиотека просто обезьяна исправляет (IP|TCP|UDP|SOCKS)Socket классы, предоставляемые библиотекой socket, для использования Resolv преобразователя DNS.

В случае SOCKSSocket исправление обезьяны вмешивается только тогда, когда интерпретатор Ruby скомпилирован с флагом --enable-socks. Итак, давайте посмотрим, как библиотека resolv-replace справится с этим сложным делом

Обратите внимание на строку 10 модификатора-if. Действительно, чтобы выбрать исправление этого класса или нет, библиотека resolv-replace просто проверяет, определена ли константа SOCKSSocket с помощью ключевого слова defined?. Действительно, как было показано в предыдущем разделе, SOCKSSocket определяется только в том случае, если интерпретатор Ruby скомпилирован с использованием --enable-flag.

Итак, поскольку ключевое слово class является лишь синтаксическим сахаром для определения класса и открытия класса, вы можете вызвать модификатор if, чтобы выполнить этот код (или нет).

Теперь давайте посмотрим, как использование defined? может положительно повлиять на производительность вашего приложения.

определено? (yield) vs block_given?

Если в вашей программе вы имеете дело с огромным количеством блоков, то defined? yield определенно может стать настоящей оптимизацией производительности вашей программы. Действительно, чтобы проверить, передан ли блок вашему методу, вы обычно используете метод Kernel#block_given?

Здесь method_with_block_given проверяет, передан ли блок в качестве аргумента, используя Kernel#block_given?. Если да, то вызывается yield и выполняется блок. В противном случае block_given? возвращает false, а yield никогда не выполняется.

Ruby предоставляет другой способ достичь того же результата: defined?(yield)

Основное различие между этими двумя выражениями в том, что defined?(yield) быстрее, чем Kernel#block_given?. Действительно, это ключевое слово, когда block_given? - метод. Таким образом, block_given? работает медленнее из-за стоимости вызова метода, добавленной к стоимости Пути поиска метода.

Давайте создадим отчеты benchmark-ips, чтобы узнать, в чем разница между defined?(yield) и block_given?

Мы видим, что block_given? на 1,27x медленнее, чем defined?(yield).

Но, как видно из приведенного выше теста, мы можем звонить block_given 9,897 млн ​​раз в секунду. Так что имейте в виду, что эта оптимизация актуальна только при большом количестве вызовов блоков.

Заключение

defined? - не самое популярное ключевое слово в Ruby. Тем не менее, в некоторых ситуациях это ключевое слово становится мощным активом для повышения производительности вашей программы или для обработки сложных случаев, когда константа, метод и т. Д. Загружаются условно. Не стесняйтесь поделиться с нами своим опытом использования этого ключевого слова в разделе комментарии.

Вуаля!

«Старый пруд» Мацуо Башō

Старый тихий пруд

Лягушка прыгает в пруд -

Всплеск! Снова тишина.