Pull to refresh

Python vs Ruby

Фаматек corporate blog Programming *
Данная флеймообразующая статья призвана собрать в одном месте актуальную информацию по преимуществам Python над Ruby и Ruby над Python. Основываясь на собственном многолетнем опыте использования обоих языков, я постарался ограничить сравнение языками как таковыми и их стандартными библиотеками — сравнение web фреймворков, сред разработки и доступных библиотек не включены в статью, так как здесь и без меня немало копий сломано.


Начнем с Python, потому что по алфавиту


  • Документация намного лучше, чем у Ruby. С вступительной частью, литературными отступлениями и многочисленными примерами. У Ruby многие модули, например DL или Win32API не документированы вообще, документация в целом значительно слабее.
  • Используются настоящие потоки операционной системы. Несмотря на то, что оба языка используют GIL (global interpreter lock), использование настоящих потоков позволят коду на Python выполнять в отдельных потоках блокирующие операции — например, вызов shell скрипта или функций операционной системы — и при этом не блокировать другие потоки. В Ruby до версии 1.9 использовался один настоящий поток, а переключение между потоками языка эмулировалось. На практике это приводит к тому, что если в отдельном потоке Ruby вызвать shell скрипт (например, копирование файлов) или функцию операционной системы (например, показать окошко с сообщением) — то все остальные потоки в данном скрипте останавливались. Начиная с версии 1.9 Ruby использует настоящие потоки операционной системы, но на данный момент (версия 1.9.3-p125) множество недоработок не позволяют получить от этого преимущество — в частности, Ruby крайне не любит поднимать GIL при вызовах блокирующих операций, так что попытка показать окно операционной системы в отдельном потоке так же остановит остальные — на этот раз потому, что не будет поднят GIL.
  • Поддержка unicode — в Ruby она появилась только начиная с версии 1.9, процесс перехода на которую пока далек от завершения.
  • Поддержка именованных аргументов функций. В Ruby данный подход можно эмулировать, передав последним аргументом словарь, но это увеличивает количество кода.

  • Очень хорошая встроенная библиотека ctypes для взаимодействия с операционной системой. Встроенная в ruby библиотека dl намного хуже документирована и сложнее в использовании — авторы рекомендуют использовать gem 'ffi'.
  • Функция является объектом — ссылку на нее можно поместить в переменную, массив, передать другой функции. В ruby идентификатор функции сам по себе является вызовом, поэтому для передачи ссылки на функцию ее нужно оборачивать в промежуточный объект, «proc», что усложняет код.

  • Поддержка декораторов — возможность добавлять к объектам аннотации, меняющие их поведение. В ruby это можно эмулировать с помощью интроспекции — но код становится сложнее, требует велосипеда с этой самой интроспекцией, которая еще и не очень быстрая.

  • Встроенная поддержка JSON. В ruby — только начиная с версии 1.9
  • Встроенная поддержка SQLite. Ruby не имеет встроенных средств работы с базами данных.
  • Встроенный GUI, «Tk», одинаково хорошо поддерживается на всех платформах. В Ruby тоже есть Tk, но инсталлятор для Windows по умолчанию его не ставит, а в OSX начиная с 10.6 он не работает для поставляемого с системой Ruby и нужно его перекомпилировать, что в целом не очень просто.
  • В Ruby исключение, брошенное не в главном потоке, не обрабатывается обработчиком исключений по умолчанию.
  • Поддержка распаковки и запаковки архивов в стандартной библиотеке.
  • Хорошая поддержка GUI библиотеки Qt для всех поддерживаемых платформ. А Qt, это, как известно — сила.
  • Поддерержка named capture groups в регулярных выражениях. В Ruby — только начиная с версии 1.9
  • В целом более распространен. Если у какой-нибудь программы или библиотеки есть binding (VirtualBox, Qt, GTK) то в большинстве случаев это будет Python.
  • Стабильные версии 2.6 и 2.7 почти не отличаются друг от друга и являются мейнстримом, переход на 3.x — в очень отдаленной перспективе. У Ruby сейчас активно идет переход с несовместимых веток 1.8 на 1.9 — довольно болезненный, мучительный и порождающий косяки.


Возникло впечатление, что Python лучше? Смотрим со стороны Ruby


  • Интерполяция строк позволяет включать в строки код на Ruby, автоматически подставляя в строку результат его выполнения.

  • Встроенная поддержка openssl. Для python — либо использовать ActivePython с не очень удобной и слабо документированой реализацией pyopenssl, либо самому ставить более удобную m2crypto — которая не то чтобы особо легко ставится, особенно под windows.
  • Поддержка создания внутренних DSL: блоки, instance_eval, вызов функции без скобок.
  • Удобный механизм вызова shell команд и получения результата их работы — всего два символа `. Корректно работает с путями, содержащими пробелы — чего не скажешь о модуле subprocess в Python, где для корректной работы с пробелами приходится передавать команду и ее аргументы не строкой, а списком.
  • Возможность включать модули по относительному пути. Python технически это может, но большим количеством кода и с рядом неприятных спецэффектов.

  • Встроенная поддержка OLE в Windows. В Python есть хороший модуль pyWin32 — но его надо либо устанавливать вручную, либо устанавливать ActivePython, где он идет в комплекте.
  • Индексирование за пределами коллекции возвращает nil, что позволяет в ряде случаев писать очень лаконичный код.
  • Удобный синтаксис подавления ожидаемых ошибок.

  • В стандартную библиотеку входит неплохой шаблонизатор «erb».
  • Возможность создания временных папок с автоматическим удалением. В Python такая возможность появилась только в версии 3.2 — а это совсем отдаленное будущее.
  • Есть языковая конструкция switch. А в python — нету.
  • Начиная с версии 1.9 named capture groups в регулярных выражениях можно автоматически превращать в переменные.

  • Лучшая поддержка работы со временем и датой. Стандартная библиотека Python даже с UTC не позволяет работать.
  • Чтение содержимого файла в Windows без спецэффектов. В Python файл по умолчанию открывается в «текстовом режиме», что автоматически конвертирует переводы строки и обрывает чтение при достижении волшебного символа EOF, что может привести к неприятным багам.
  • У потоков есть метод exit, который позволяет штатно остановить работу потока снаружи. В Python остановить работу потока «снаружи» нельзя — нужно встраивать собственные велосипеды с флагом остановки.


Выводы


Сверяемся со списком и выбираем язык под задачу. Ruby традиционно лучше справляется с обработкой текста, DSL, автоматизацей shell (смотрим на rake и завидуем). Python — многопоточность, GUI, биндинги ко всему что движется, лучшая документация и поддержка индустрией. При использовании Ruby, если есть возможность, лучше использовать версии 1.9.x — там слишком много изменений к лучшему по сравнению с 1.8.x. Вопросы, комментарии, флейм? Добро пожаловать в комменты.

P.S. Предвидя комментарии вида «а мне для <пункт сравнения> больше нравится <язык>, потому что <причина>». На вкус и цвет фломастеры разные, я рассказываю с колокольни своего практического опыта и моих задач, которые, к тому же, далеки от сайтостроения. В статье описаны различия, которые я расставил как «сильные» и «слабые» стороны исключительно на свой субъективный, хотя и профессиональный, взгляд. Надеюсь, статья станет неким базисом, на основании которого разработчики смогут выбрать язык под свои задачи чуть более осознанно.

P.P.S Предвидя комментарии вида «в <пункт сравнения> код на <язык> написан неправильно — это делается по другому». Примеры утрированы и сравнивают одинаковые возможности языков, без учета лучших практик их применения. Исключительно в целях предотвратить распухание статьи. Хочется быть компактным.
Tags: pythonruby
Hubs: Фаматек corporate blog Programming
Total votes 201: ↑163 and ↓38 +125
Comments 349
Comments Comments 349

Information

Founded
1999
Location
Россия
Website
www.radmin.ru
Employees
11–30 employees
Registered