Статьи

PHP против RUBY: в чем смысл?

Вы, несомненно, читали одну из многочисленных статей, сравнивающих достоинства PHP с Ruby, или, чаще всего, с моим раздражением, PHP против Rails. Надеюсь, как и я, вы найдете такие статьи бессмысленными упражнениями и ничего кроме языкового троллинга. Это просто не ровное игровое поле.

Каким-то образом разработка для Интернета объединяет этих двух разных животных для сравнения. PHP aka Personal Home Page Tools (спасибо википедии ) — это язык / фреймворк, разработанный специально для Интернета. Ruby, с другой стороны, является языком общего назначения, задуманным одним человеком Матцем, в стремлении создать утопический язык программирования.

Начиная с PHP, вы, вероятно, создадите несколько страниц с кодом в HTML. Затем, осознав, насколько болезненным может быть поддержание, вы начнете абстрагировать свою бизнес-логику и уровни представления, используя что-то вроде Smarty . Вы получите немного больше объектно-ориентированного подхода и, без сомнения, получите что-то вроде Zend Framework или CodeIgniter для разработки своих собственных приложений. Надеюсь, все это звучит знакомо.

Когда дело доходит до Ruby, многие разработчики игнорируют такой разумный путь развития. Я знаю, что, конечно, сделал. Где большинство людей начинают с Ruby, включая меня? Рельсы, конечно. Мы смотрим видео «Построить блог», и, конечно же, мы все проданы. Я никогда не отговаривал бы ни от кого брать Rails и работать с ним, но это не Ruby для начинающих. Когда вы используете Rails, многие великие разработчики тратят много времени на то, чтобы абстрагироваться от всех этих ужасных мелочей. Миграции просто работают, маршрутизация просто работает, ведение журнала и тестирование, и вы можете использовать его. Rails — это фреймворк, позволяющий сосредоточиться на проблеме, которую вы хотите решить.

Привет Стойка

Хорошая причина начать с Rails заключается в том, что когда речь заходит о разработке для Интернета, сам по себе Ruby является не чем иным, как навязчивым. Конечно, мы можем использовать стандартный CGI класс библиотеки, загрузить файл на сервер, сделать его исполняемым, и все готово. Сравните это с PHP-скриптом.

Даже DHH писал о непосредственности PHP. Ваше удовлетворение мгновенно. Хотите протестировать быстрое исправление ошибки? Просто нажмите обновить в браузере. Ничего из этого перезапускающего дворняги, пассажира или чего-то еще не требуется.

Так как же мы можем получить такие мгновенные веб-приложения на Ruby, не прибегая к rails s ? Ну, а как насчет того, чтобы использовать фреймворк, который использует сам Rails? Стойка

Rack — это интерфейс между приложениями Rails и протоколом HTTP. Это также основа практически всех веб-фреймворков Ruby, включая Sinatra и merb .

Rack включает в себя весь тот низкоуровневый код, который разработчики фреймворка дублировали в разных проектах. По сути, он подхватывает любой доступный веб-сервер и использует его для обслуживания ваших приложений (под веб-сервером мы говорим о монгрелах, WEBrick, тонких и так далее).

Чтобы начать работу с Rack, достаточно просто установить гем, создать файл стойки (* .ru) и запустить приложение.

Привет мир Rack выглядит следующим образом ( hello.ru ):

 class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, ["<h1>Hello world!</h1>"]] end end run HelloWorld.new 

Затем в консоли, rackup hello.ru . Вы увидите немного выходных данных сервера с портом, на котором запущен сервер (обычно 9292). Просто перейдите на http: // localhost: 9292 и увидите славу.

Чтобы разобрать это простое приложение (и это приложение), в основном у нас есть метод с именем call который получает среду и возвращает массив из трех вещей: status, headers и body. Под средой мы не говорим о постановке, производстве и т. Д. Вместо этого это набор переменных CGI, который мы видим в $_SERVER PHP $_SERVER , REQUEST_METHOD и т. Д.

Коды состояния довольно понятны, и содержимое хеша заголовков также будет знакомо. Тело, которое мы видим в примере hello world, является массивом, или, более конкретно, оно должно отвечать each . Наконец, в конце файла мы видим, что метод run экземпляр нашего приложения hello world.

Итак, основные правила приложения Rack: у него должен быть call метода, который принимает хэш среды и возвращает статус, заголовки и тело, а тело должно отвечать each .

Эхо «Hello World»

Мы видели базовое приложение Rack, но как это сравнить с простотой:

 <? php echo "<h1>Hello World</h1>"; ?> 

На первый взгляд, это, конечно, кажется более запутанным, поэтому давайте посмотрим, что Rack дает вам, чтобы сделать его более привлекательным.

Строитель

Когда дело доходит до привет, PHP довольно трудно победить. К счастью для нас, Rubyist, приложения hello world пользуются низким спросом, а Rack предлагает гораздо больше, чем просто оберточные серверы. Сам Rack поставляется со многими приложениями micro Rack, которые помогут нам в создании наших фреймворков. Они включают в себя все полезные вещи, такие как ведение журнала, сеансы, отображение URL и так далее.

Одной из жемчужин Rack должно быть Rack::Builder . Это предметно-ориентированный язык (DSL), который позволяет легко создавать и объединять приложения Rack. Подумайте о создании приложения PHP, которое имеет открытую страницу и секретную страницу. В PHP мы могли бы создать два файла, которые выполняют эти обязанности. Альтернативой может быть создание файла .htaccess который направляет все входящие запросы в один файл следующим образом.

 RewriteEngine on RewriteBase / RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+)$ /index.php?page=$1 [L] 
 <?php if ($_SERVER['REQUEST_URI'] == '/secret') { echo "Shhhh"; } else { echo "This is public"; } ?> 

Не так уж плохо, его реализация с использованием Rack :: Builder может выглядеть примерно так:

 app = Rack::Builder.new do map "/" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["This is public"]] } end map "/secret" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Shhhh"]] } end end run app 

Довольно аккуратно? Здесь мы реализовали Builder, чтобы отобразить URL для заданных действий. Эти действия — просто Proc теперь, когда мы находимся на ногах, они возвращают золотое трио, которое мы видели в нашем приложении hello world .

Это также бесконечно масштабируемо. Например, давайте посмотрим на путь, такой как «/ secret / files». Наша версия PHP становится достаточно волосатой, чтобы оправдать переосмысление (мы не хотим идти дальше по линии добавления файлов в относительные каталоги, не так ли?), В Rack мы просто вкладываем некоторые блоки map .

 map "/secret" do map "/" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Shhhhh"]] } end map "/files" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Here be dragons"]] } end end 

Надеюсь, вы почти проданы на стойке. Пока мы все еще чувствуем любовь, давайте немного оживим ее, добавив еще несколько странных игрушек Rack.

Стойка = Чертовски сексуально

Мы упоминали ранее, что Rack — это больше, чем интерфейс сервера. Он поставляется с множеством «компонентов», которые сами являются стоечными приложениями. Теперь мы посмотрим, как мы можем реализовать пару из них.

Я всегда нахожу логирование полезным при разработке приложений.

 require 'logger' app = Rack::Builder.new do use Rack::CommonLogger Logger.new('my_rack.log') map "/" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["This is public"]] } end map "/secret" do map "/" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Shhhhh"]] } end map "/files" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Here be dragons"]] } end end run app 

Мы говорили о секретных областях и драконах, поэтому нам лучше запереть все это. Базовая аутентификация HTTP всегда хороша для обеспечения безопасности.

 require 'logger' app = Rack::Builder.new do use Rack::CommonLogger Logger.new('my_rack.log') map "/" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["This is public"]] } end map "/secret" do use Rack::Auth::Basic do |user, password| user == 'super_user' && password == 'secret' end map "/" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Shhhhh"]] } end map "/files" do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Here be dragons"]] } end end end run app 

Это было невероятно легко, я помню дни, когда настраивали файлы .htpasswd и так далее.

Rackup

Я начал эту статью, как если бы это была чушь PHP против Ruby. И на протяжении всей статьи я делал ссылки на то, как мы можем сделать это на PHP, и сравнивал это с Rack. Все это было хитрым ходом, охотящимся на языкового тролля во всех нас. Факт, у обоих есть свои достоинства, и даже сравнение Rack с PHP вряд ли справедливо.

Я надеюсь, что это дало вам представление о том, насколько гибким, обслуживаемым и радостным является использование Rack. Это отличное место, чтобы начать изучать Ruby, потому что есть достаточно «магии», чтобы поддерживать наш интерес, но недостаточно, чтобы затенить обучение.

Мы еще не закончили там, хотя. Вы будете помнить все большие фреймворки, построенные поверх Rack. На самом деле мы можем реализовать мистическое промежуточное ПО с помощью Rack, которое перехватывает нормальный поток наших приложений и временно передает управление приложениям Rack. Может быть страшно, но Rails любит это.