Ruby VS PHP, Rails VS Zend Framework

Итак, в предыдущей заметке мы создали наше первое приложение. Какие выводы можно из этого сделать? Предлагаю обсуждение, что лучше для веб-разработки Ruby on Rails или Zend Framework. Понимаю, что из этого может вырасти холивар, но мне интересны конкретные аспекты этих фреймворков. И да, будем сравнивать правильно язык с языком (Ruby VS PHP), фреймфорк с фреймворком (Rails VS Zend Framework). Полагаю что результаты можно будет экстраполировать и на другие PHP -фреймворки (Symfony, Koxana, CodeIgniter).

Небольшая легенда: (+) – это преимеущество Rails, (-) – это недостаток, (.) – это хз что такое 🙂 

  1. (+) Rails – MVC-фреймворк, а значит переходящим на него с ZF/Symfony будет легко понять чего где лежит.
  2. (-) Ruby – интерпретируемый язык, а значит возможны некоторые тормоза.
  3. (+) В режиме development классы приложения перезагружаются сами при каждом запросе, а значит нам достаточно просто обновить страницу, как в случае с PHP, чтобы увидеть результат. НО в режиме production классы кэшируются и не перзагружаются при каждом запросе. Этого я давно хотел от Zend Framework, потому что иклудить по 250 файлов на каждый запрос – это кошмар и дикие тормоза. Тут работает прямо из коробки.
  4. (-) Для Ruby на данный момент нет байт-код кэшеров, а для PHP – есть и отлично работают. Запишем это ему в плюсы. Хотя сейчас активно разрабатывается проект Rubinius, который позволяет производить прекомпиляцию кода Ruby, за счёт чего увеличивается производительность. Пока не пробовал его в деле, да и Ruby 1.9 он вроде не поддерживает.
  5. (+) Rails имеет развитые консольные утилиты. Для Zend’а в принципе тоже есть Zend_Tool, но я если чество им не пользовался.
  6. (+) ORM. Да, здесь ActiveRecord идет как автоматически устанавливаемый гем, а для ZF придется еще интегрировать Doctrine ORM, т.к. встроенная Zend_Db слишком простая.
  7. (+) Установка приложение на порядок проще, чем установка PHP приложения. Не надо писать свой инсталлятор, всё уже есть, и зависимости выкачиваются и ставятся автоматически.
  8. (+) Развертывание приложения – тоже дело пяти минут, при готовой среде. Тестовое приложение Rails я довольно быстро развернул у хостера Heroku. Причем все гемы поставились автоматом, всё само настроилось и запустилось. Я лишь заворожено смотрел на сообщения в консоли. А когда набрал http://netandreus.heroku.com/ обалдел, увидев мое приложение.
  9. (-) Всё-таки очень трудно найти хостера с рельсами. Пока с этим проблемы, но думаю учитывая скорость его развития будет проще. Но всегда есть возможность взять VDS и сделать там всё, что нужно.
  10. (.) Масштабируемость. Здесь есть варианты с ПО Mongrel вместо WebRick, mod_passanger для Apache/Nginx и балансировщиком нагрузки. Пока не знаю, не тестил. Кстати, говорят что, ActiveRecord здорово тормозит на большиз базах. Опять же пока не попробуешь – не узнаешь.
  11. (+) В Ruby качественный ООП, например такой код отлично сработает. 5.month + 10.days Month и Days это методы объектов 5 и 10 O_0
  12. (+) Возможности метапрограммирования Ruby. Начал изучать эту тему, пока ничего не получилось, но желание поизучать есть огромное. Начал с изучения ActiveSupport.
  13. (+) Интеграция с языками более низкого уровня. Здесь у руби, как мне кажется, всё гораздо лучше чем у ZF. Я помню опыт создания своей C (именно С, а не C++) библиотеки и её подключения к PHP. Была та ещё работёнка. Руби же сейчас прекрасно работает с Java, (см. проект JRuby), в чём я недавно смог убедиться, скачав приложение Ruboto. По поводу C++ не копал пока, но знаю, что некоторые гемы написаны на сях, а значит такая возможность есть.
  14. (.) Асинхронное программирование. В Руби есть EventMachine, в PHP – PHPDaemon. Вчера сделал скриптик на EM, и имхо это явно лучше чем node.js
  15. (-) Руби более сложный язык. Более сложный и гибкий. С одной стороны это плохо, т.к. на первых этапах довольно тяжело обучиться. С другой стороны – это некий порог для быдлокодеров, которые не смогут попасть в ряды разработчиков.
  16. (-) В Zend_Framework есть классы на все случаи жизни, в рельсах я такого многообразия пока не наблюдаю. Да, есть интересные гемы, но в зенде это всё более целостно и в тоже самое время почти любой класс можно использовать отдельно. Никто не заставляет тебя использовать весь фреймворк – бери только то, что нужно. В рельсах же ты либо на рельсах – либо нет.
  17. (-) Документация пока оставляет желать лучшего, для Rails 3 очень мало материалов, многие старые команды не работают. Взять хотя бы rails script/generate который теперь выглядит как rails generate и другие. Это конечно прекрасно, что фреймворк развивается, но сложно искать материалы.
  18. (-) Хотя руби и работает под Windows, но разрабатывать ПО там, как мне кажется, – каторга. Хорошо, что я сижу под Ubuntu 🙂

Если есть мнение, не стесняйтесь – высказывайтесь в комментах!

8 Comments

  1. 5. Никогда ничего не писал на пхп для консоли. Наверное это личное, но для меня слова “пхп” и “консоль” не совместимы. Для консоли все всегда писал на perl, сейчас использую ruby.
    2. Тогда и для php запиши это как минус.
    10. Любая ORM может тормозить. Это зависит от того, как будешь писать. Яркий пример: если при удалении объекта на дочернии объекты стоит :dependent => :destroy, а дочерних объектов дохуя, то AR будет сначала получать строку из БД, конструировать объект, удалять запись в БД и замораживать объект. Сам же AR работает на поряжки быстрее Doctrine.
    Кроме Mongrel есть еще thin и unicorn – они шустрее.
    11. Это не есть встроенное в язык, это нам дает gem active_support
    14. Та же самая фигня, не лучше и не хуже. Только вот nodejs быстрее.
    16. Вообще не верно. Есть, к примеру, sinatra, есть merb. Для небольших приложений – вполне. Да и гемов на порядок больше, чем пакетов ZF.
    17. Пожалуйста: http://edgeguides.rubyonrails.org/

    1. 10. Любая ORM может тормозить. Это зависит от того, как будешь писать. Яркий пример: если при удалении объекта на дочернии объекты стоит :dependent => :destroy, а дочерних объектов дохуя, то AR будет сначала получать строку из БД, конструировать объект, удалять запись в БД и замораживать объект. Сам же AR работает на поряжки быстрее Doctrine.M

      В данном случае выигрыш идёт за счёт кэширования классов, при других условиях не факт, что она была бы быстрее.

    2. 5. Имеются ввиду иные консольные утилиты:
      К примеру вы можете посмотреть в консоли каким образом обрабатываются те или иные запросы. Как работают ново созданные реляционные связи. Как обрабатываются роуты. Дебаггер из коробки позволяет организовать консоль посреди рабочего запроса, получить состояния всех объектов. Из консоли удобно тестируются разнообразные обработчики прежде чем прикручиваются к production серверу и т.п. Т.е. консоль имитирует среду в которой работает сайт. Если работает в консоли с вероятностью 75% можно включать в проект.
      11. ActiveSupport написан на ruby. Вы можете своими руками присвоить классу Integer методы month, months и months_ago своими руками В первую очередь – способности языка, это его “ООПешность”, без нее Rails бы не получился, что и имел в виду автор.

  2. Насчет хостинга вроде locum.ru хороший 80 руб/мес, прям как шаровые,
    Хочу поставить минус zendу он вроде и мощный но вот решений вроде как регистрация/активация/напоминание/авторизация из коробки – нету или ajaxы эти тащишь из вьюхи в контроллер, везде код надо подбирать типа view принадлежит controller класу, в руби @task = Task.all и все во вьюху передал, уже не говоря за аяксы, а роут как тебе зендовый?, ладно 20 роутов, а если их 120, а REST какой прекрасный у рельса html xml json как хоч так и забирай))

    1. Очень тяжело читать ваш комментарий 🙂 Все решения вроде авторизации, регистрации и т.д. – есть из коробки (см. мануал). Роуты – отличные, код из вида в контроллер переносить не надо. Всё остальное зависит от кривизны рук.

  3. 12: простой работающий в production пример
    [‘price_up_filtered’,’price_down_filtered’, ‘sold_filtered’].each do |meth|
    pattern = ”
    def #{meth}

    @favorites = Offer.in_favorites(current_user.id).map(&:id)
    @offers = Offer.not_in_blacklist(current_user.id).where(filter_queue(‘#{meth.split(‘_’)[0..-2].join(‘_’)}’)).page(params[:page])
    @current = ‘#{meth}’
    respond_to do |format|
    format.js { render :partial => ‘tab-offers’ }
    end
    end


    self.class_eval pattern
    end

    создаст три метода

    def price_up_filtered
    @favorites = Offer.in_favorites(current_user.id).map(&:id)
    @offers = Offer.not_in_blacklist(current_user.id).where(filter_queue(‘price_up’)).page(params[:page])
    @current = ‘price_up’
    respond_to do |format|
    format.js { render :partial => ‘tab-offers’ }
    end
    end

Leave a Comment