Множество интерпретаторов и сред выполнения языка программирования Ruby
Опубликовано: 2022-03-11Введение
Так же, как существует множество оттенков рубинового камня, существует множество реализаций интерпретатора Ruby.
Наиболее часто используемым интерпретатором Ruby является эталонная реализация Ruby MRI, разработанная на C создателем Ruby (Юкихиро Мацумото) и основной командой Ruby.
В нашем Руководстве по найму Ruby on Rails упоминается, что некоторые недостатки Rails потенциально могут быть устранены или устранены с помощью альтернативного интерпретатора Ruby. В этой статье демонстрируются различные существующие на сегодняшний день реализации и среды выполнения интерпретатора Ruby, обсуждаются преимущества и недостатки каждой из них.
История версий Ruby (и как она влияет на альтернативные реализации)
К сожалению, эквивалента справочника по языку Python для Ruby не существует (ISO/IEC 30170:2012 описывает Ruby 1.8/Ruby 1.9, но для Ruby 2.x не существует соответствующей спецификации). В отсутствие какой-либо такой спецификации языка разработчики Ruby обычно полагаются на управляемую сообществом RubySpec, которая определяет ожидаемое поведение языка Ruby с помощью тестов, которые можно запускать в любом интерпретаторе Ruby. Поэтому RubySpec используется разработчиками Ruby для проверки соответствия поведения их реализаций Ruby стандарту де-факто.
Из-за отсутствия формальной спецификации новые выпуски Ruby часто просто соответствуют новым выпускам Ruby MRI. Стоит отметить, что существует открытый вопрос, в котором обсуждается процесс проектирования отделения Ruby (языка) от Ruby MRI.
Однако, учитывая текущую тесную связь между языком Ruby и эталонной реализацией MRI, разработчики альтернативных реализаций Ruby иногда с трудом успевают за языковыми изменениями, вносимыми в каждую новую версию MRI.
Никогда еще это не было так сложно, как при переходе между Ruby 1.8 и Ruby 1.9. В 2007 году, стремясь очистить и консолидировать синтаксис Ruby (поскольку язык развивался за десятилетие, прошедшее с момента выпуска Ruby 1.0), основная команда Ruby выпустила Ruby 1.9.0, версию, которая привнесла в язык много несовместимостей с предыдущими версиями. . В результате не все реализации Ruby приложили усилия, необходимые для синтаксического перехода с 1.8 на 1.9. Таким образом, существует несколько реализаций Ruby на основе 1.8, которые больше не используются сообществом, но которые вы все еще можете найти в Интернете или о которых говорят старые руки Ruby.
Каждое Рождество выпускается новая версия Ruby MRI в соответствии с принципом семантического управления версиями. Ruby 2.0 (выпущен в 2013 г.) и 2.1 (выпущен в 2014 г.) представили дополнительные языковые функции, которыми могут воспользоваться разработчики Ruby, не теряя при этом обратной совместимости с Ruby 1.9.
Зачем использовать альтернативную реализацию Ruby? Что не так с МРТ?
Существует множество альтернативных реализаций Ruby, поддерживающих широкий спектр вариантов использования и сред. Среды Java Enterprise. Мобильные приложения. Реализации JavaScript. Машины с низким CPU/RAM. В дополнение к поддержке этих вариантов использования альтернативные реализации могут иногда также предлагать дополнительный прирост скорости или более эффективное использование памяти, в зависимости от характеристик вашего приложения.
В течение долгого времени многие разработчики Ruby on Rails использовали Ruby Enterprise Edition (REE) вместо MRI, используя лучшие методы управления памятью в REE по сравнению с версией MRI того времени. (Впоследствии производство REE было прекращено, хотя в 2012 г.)
Хотя MRI является реализацией Ruby по умолчанию, это не обязательно правильный выбор для всех сред и сценариев. Например, поддержка параллелизма в MRI хуже, чем в JRuby или Rubinius. Кроме того, хотя схемы памяти и сбора мусора MRI постоянно совершенствуются, у них все еще есть некоторые проблемы.
Приведенный ниже обзор реализаций Ruby призван помочь вам в выборе интерпретатора, наиболее подходящего для операционных целей и ограничений вашего проекта.
Интерпретатор Ruby от Маца (MRI) / CRuby
Написанная на C основной командой Ruby под руководством Юкихиро Мацумото («Мац», создатель Ruby), MRI является эталонной реализацией Ruby, которая служит стандартом де-факто. Если поставщик ОС включает версию Ruby, например, как часть установленного программного обеспечения ОС, это обычно версия MRI. MRI выигрывает от большего количества оплачиваемых членов основной команды, чем любая другая реализация Ruby, а также от дополнительных ресурсов, выделенных людьми или компаниями, которые хотят улучшить экосистему Ruby.
Новая версия Ruby MRI, часто реализующая новые языковые функции в дополнение к изменениям стандартной библиотеки, выпускается каждое Рождество. Сначала функции реализуются в Ruby MRI, обычно на основе обсуждений в списке рассылки основных разработчиков Ruby. Другие реализации Ruby отстают, в некоторых случаях даже на годы.
JRuby
JRuby — это версия Ruby, реализованная поверх виртуальной машины Java (JVM). По мере того, как языки, помимо Java, становятся популярными для работы поверх JVM (я смотрю в вашем направлении, Clojure и Scala), реализация Ruby на основе JVM, вероятно, будет набирать популярность.
Ruby в JVM также означает, что Ruby может работать везде, где может работать Java (например, на телефонах Android, с использованием Ruboto). Кроме того, благодаря функциональной совместимости JVM код JRuby может использовать платформу Java, включая как стандартные, так и сторонние библиотеки.
JRuby также полезен для переноса решения на основе Rails в среду развертывания только для Java, упаковки приложения Rails в виде файла .war для развертывания в контейнере Tomcat или в виде апплета Java, работающего как часть вашего веб-интерфейса. , Например.
Тем не менее, для тех, кто не привык к JVM, JRuby приносит стандартные проблемы, связанные с JVM, такие как медленный запуск интерпретатора Ruby, отладка проблем CLASSPATH, если вы используете сторонние библиотеки Java, большее использование памяти и тот факт, что теперь ваш код должен быть написан с учетом соображений безопасности потоков.
Кроме того, некоторые функции Ruby (C API и один из мощных инструментов самоанализа Ruby, модуль ObjectSpace) не реализованы в JRuby.
При этом преимущества использования JVM могут перевешивать недостатки для определенных ситуаций или проектов. JVM позволяет оптимизировать производительность, например, включить JIT-компилятор или использовать собственные объекты Java и API-интерфейсы.
В качестве примера убедительного варианта использования JRuby у моего бывшего коллеги однажды возникла проблема с интенсивным использованием ЦП, которую он первоначально решил с помощью потоков в Ruby 1.9.3. Когда он переключился на JRuby и использовал java.util.concurrent.Executors , он увидел улучшение производительности на несколько порядков (в десятки тысяч раз быстрее) для этой операции. Смотрите его эксперимент здесь.
Рубиний
Rubinius — это реализация Ruby, которая реализует общую среду выполнения для динамических языков поверх виртуальной машины низкого уровня (LLVM). Используя эту инфраструктуру и технологию JIT-компилятора, Rubinius часто может запускать код Ruby с меньшими затратами, чем MRI.
Rubinius также построен с использованием как можно большего количества Ruby, чтобы сделать разработку интерпретатора/среды выполнения быстрее и проще.

Забавный факт: RubySpec изначально появился в процессе внедрения Rubinius.
Как и JRuby, Rubinius включает JIT-компилятор, улучшенное управление памятью и более совершенную виртуальную машину, чем Ruby MRI. Однако, в отличие от JRuby, Rubinius поддерживает библиотеки Ruby C, а основы Rubinius написаны на C++, а не на Java.
Rubinius может быть хорошей серединой, когда вам нужна высокая производительность на ваших серверах Rails без кривой обучения или других недостатков JRuby.
мруби
mruby разработан как встраиваемая версия Ruby (поддерживающая Ruby 1.9.3). С помощью mruby вы можете предлагать Ruby в качестве языка сценариев/автоматизации в нативных приложениях, использовать его для сценариев игр и даже для программирования плат микроконтроллеров, таких как Raspberry Pi.
Если ваша платформа сильно ограничена в ресурсах, mruby может быть для вас просто интерпретатором Ruby. mruby также используется для:
- Создавайте приложения для iOS (как конкурент RubyMotion, обсуждаемый ниже)
- Встраивайте Ruby в приложения iOS для ускорения разработки
- Предложите конечным пользователям встроенный язык сценариев для целей автоматизации
По мере того, как Интернет вещей становится все более и более реальностью, домашняя автоматизация становится все более популярной, а чрезвычайно портативные (и относительно мощные) компьютеры становятся все более распространенным явлением, ландшафт целевых платформ для поддержки становится все более разнообразным. mruby помогает сделать это с помощью того же продуктивного языка, который можно использовать на рабочем столе.
Опал
Opal — это транспилятор для преобразования Ruby в JavaScript.
С появлением Coffeescript разработчики узнают, что им не нужно вводить JavaScript, чтобы получить JavaScript. Хотя Coffeescript, по общему признанию, имеет свои преимущества, используйте его достаточно долго, и вы обязательно столкнетесь с вещами, которые вам не нравятся в этом языке.
Введите Opal: введите Ruby, получите Javascript . Довольно круто.
Opal стремится быть как можно более совместимым с другими реализациями Ruby и поэтому также тестируется на соответствие подмножеству RubySpec. Однако существуют некоторые несовместимости, связанные с природой JavaScript и сред выполнения JavaScript. Например, строки и символы в Opal равны, и Opal не предоставляет каких-либо потоков или механизмов выполнения оболочки.
Opal работает автономно или может использоваться как часть конвейера ресурсов Rails (например, для автоматического переноса вашего файла somefile.js.rb в JavaScript).
Возможно, у вас есть проблемная область, хорошо подходящая для шаблона асинхронного параллелизма JavaScript (например, небольшая служба Node.js), но вам нужен язык или определенные жемчужины из пространства Ruby. Опал может быть хорошим решением для вас в этом случае.
Или, возможно, вы хотите написать полноценное веб-приложение на Ruby. С Опалом вы можете. Пусть один интерпретатор Ruby запускает ваш код Ruby на стороне сервера, а затем пусть Opal генерирует JavaScript для запуска на стороне клиента.
Opal понимает, что вы, вероятно, будете взаимодействовать с другими API-интерфейсами JavaScript (например, DOM или Node.js). Поэтому он упрощает переход на JavaScript и предоставляет некоторый синтаксический сахар Ruby по сравнению с обычными библиотеками JavaScript, такими как jQuery.
Однако ориентированная на JavaScript природа Opal является одновременно его силой и слабостью. С другой стороны, среда выполнения Opal — это среда выполнения JavaScript, а Opal зависит от проектных решений JavaScript. Поэтому, если вы ищете хорошую реализацию Ruby для написания небольшого сценария оболочки или ищете лучшую среду выполнения Ruby для своего приложения Rails, Opal, вероятно, не лучший выбор.
РубиМоушн
RubyMotion является одновременно (а) реализацией Ruby (написанной с использованием Objective-C и Cocoa) и (б) набором языковых привязок, позволяющих разработчикам получать доступ к API-интерфейсам Cocoa через Ruby.
RubyMotion — это коммерческий продукт, который позволяет вам писать собственные приложения Cocoa на Ruby. RubyMotion 2.0 позволяет писать приложения для iOS и Mac OS X на Ruby, а RubyMotion 3 обещает обеспечить такую же поддержку для Android.
RubyMotion реализует версию 1.9 языка Ruby.
Несуществующие реализации
За годы, прошедшие с тех пор, как Ruby был впервые представлен, некоторые из появившихся реализаций Ruby были заброшены или прекращены, например:
- Ruby Enterprise Edition (REE). REE был ответвлением MRI 1.8 от людей из Phusion Passenger, в котором было реализовано множество улучшений памяти и сбора мусора для веб-разработчиков. В течение нескольких лет это была реализация Ruby по умолчанию, развернутая для рабочих сайтов Rails. Однако он никогда не обновлялся для Ruby 1.9 или Ruby 2.0 и в конечном итоге был прекращен в 2012 году.
- Железный Рубин. IronRuby — это Ruby, реализованный поверх Microsoft .NET, написанный на C#, и какое-то время проект финансировался Microsoft. Заброшенный в 2011 году, IronRuby в последний раз поддерживал Ruby 1.8.6.
Заворачивать
Существует широкий выбор сред выполнения и интерпретаторов для среды Ruby. Для большинства проектов Ruby эталонная реализация Ruby (Ruby MRI) остается предпочтительным интерпретатором. Однако альтернативные реализации Ruby вполне могут быть правильным выбором для вашего проекта, в зависимости от ваших функциональных и технических целей и ограничений.
В своей роли эталонной реализации Ruby MRI быстрее получает новые языковые функции, имеет достаточно хорошие параллелизм и истории памяти (которые только улучшаются) и имеет самую широкую совместимость с гемами (некоторые частично написаны на C). В целом, MRI — надежный выбор для кода Ruby общего назначения.
Для более крупных корпоративных развертываний или в ситуациях, когда вам нужно взаимодействовать с кодом Java (или другими языками JVM) или вам нужны высокоразвитые шаблоны параллелизма, JRuby является привлекательным вариантом.
И, конечно же, если у вас есть уникальные потребности (например, написание JavaScript, работа на встроенных устройствах текущего поколения и т. д.), другие альтернативы Ruby могут оказаться именно тем, что вам нужно.
Благодаря широкому выбору исполняющих сред и интерпретаторов Ruby, Ruby демонстрирует себя как гибкий язык, полезный для широкого круга вычислительных сред, начиная от корпоративной большой железной мастерской по развертыванию Java и заканчивая программным обеспечением, которое управляет светофором в вашем офисе. вы подключили свой Raspberry Pi в прошлые выходные. Выбор правильного инструмента для правильной цели важен, да, но, надеюсь, эта статья показала вам, что Ruby — это гораздо больше, чем интерпретатор Ruby по умолчанию, который поставляется с вашей ОС.
Мир Ruby значительно расширяется благодаря альтернативным командам по внедрению Ruby, работающим с основной командой Ruby MRI по мере предложения изменений в языке. Они добавляют разнообразия сообществу разработчиков Ruby, добавляя свой с трудом завоеванный опыт реализации Ruby и свои собственные взгляды на функции, входящие в язык. Все энтузиасты Ruby в большом долгу перед этими командами. Низкий поклон им за их старания!
