Posts Tagged ‘ruby’

Я написал веб-сервер, который ничего не умеет

Четверг, Октябрь 21st, 2010

И, спрашивается, зачем?

А затем, чтобы рассказать на примере, как обрабатываются GET-запросы. Пока что мой сервер ничего не умеет, кроме обработки GET-запросов и вывода информации о клиенте, он даже не читает никакие файлы с диска. Его задача другая, показать, как происходит обработка запросов. Я это сделал потому, что как оказалось, далеко не все веб-разработчики понимают, как это происходит. Мне вот повезло, давным давно приходилось разбирать аж multipart-запросы и обрабатывать заголовки, приходящие на сервер - в бытность, когда писал свою библиотеку на Perl.

Но сейчас я сделал пример на Ruby и не поймет его только баран (или обезьяна). Я постарался максимально документировать его, чтобы было все понятно.

require 'socket' # Из стандартной библиотеки Ruby

# Открываем TCP сокет (Это можно было сделать и по-другому, но я решил
# не создавать сокет вручную, а воспользоваться более высоким уровнем).
# Как видно, сокет будет ожидать соединения (т.к. он является сервером) на
# localhost на 8000-м порту.
server = TCPServer.open('localhost', 8000)

# Бесконечный цикл.
# После того, как соединение от клиента будет принято - клиенту
# будет возвращен ответ и соединение закроется - программа перейдет
# в начало цикла, чтобы ожидать новый запрос
loop do
  # Принимаем входящее соединение клиента. Пока соединение не будет принято,
  # сокет будет ожидать его, и код ниже этой строки
  # не будет выполняться.
  client = server.accept
  client_headers = []

  # Получаем данные клиента построчно
  while line = client.gets
    client_headers << line

    # Протокол HTTP предписывает \r\n как
    # перевод строки — всегда, независимо от операционной системы.
    # Поэтому, тело запроса нам не нужно (т.к. мы обрабатываем
    # только GET-запросы. Получить тело нам понадобилось бы
    # только в POST-запросе, а в GET-запросе тела просто-напросто нет).
    break if line == "\r\n"
  end

  # Поспим 10 секунд. Я сделал это для того, чтобы проиллюстрировать кое что.
  # Попробуйте одновременно обратиться в 2-х закладках браузера к веб-серверу и
  # вы увидите, что второй запрос будет происходить в два раза дольше
  # первого, т.к. он будет дожидаться, пока обработается первый запрос. Чтобы запросы
  # обрабатывались параллельно (т.е. не стояли в очереди) - можно сделать
  # несколько тредов (воркеров).
  sleep 10

  # Возвращаем ответ клиенту и закрываем соединение. В виде тела ответа
  # показываем клиенту его же заголовки.
  client.print "HTTP/1.1 200/OK\n"
  client.print "Content-type: text/html\n\n"
  client.print client_headers.join "<br/>"
  client.close
end

Я создал TCP-сервер при помощи объекта TCPServer, но можно было сделать и на чистом объекте Socket. Просто TCPServer, который наследуется от TCPSocket, а тот, в свою очередь, от Socket - уже настроен для того, чтобы быть сервером, то есть он умеет висеть на определенном хосте и порту и ожидать входящие соединения.

Из кода видно, что:

  • Веб-сервер обрабатывает только GET-запрос
  • Он не читает никаких файлов с диска, а просто отображает информацию о клиенте, который к нему присоединился
  • Всегда отвечает со статусом 200

Можно сохранить код в файл server.rb, а затем запустить его:

ruby server.rb

Прекрасные контроллеры в Rails 3

Пятница, Сентябрь 3rd, 2010

Зацените, кто еще не видел, насколько меньше кода стало в контроллерах Rails 3! Теперь можно сказать, что контроллеры стали по-настоящему соответствующими принципу DRY. И всё это благодаря респондерам. В общем, мне нравится:

class ProductsController < ApplicationController
  respond_to :html, :xml  

  def index
    respond_with(@products = Product.all)
  end  

  def show
    respond_with(@product = Product.find(params[:id]))
  end  

  def new
    respond_with(@product = Product.new)
  end  

  def create
    @product = Product.new(params[:product])
    flash[:notice] = "Successfully created product." if @product.save
    respond_with(@product)
  end  

  def edit
    respond_with(@product = Product.find(params[:id]))
  end  

  def update
    @product = Product.find(params[:id])
    flash[:notice] = "Successfully updated product."
      if @product.update_attributes(params[:product])

    respond_with(@product)
  end  

  def destroy
    @product = Product.find(params[:id])
    @product.destroy
    flash[:notice] = "Successfully destroyed product."
    respond_with(@product)
  end
end  

В респондерах теперь содержится вся та магия по отдаче ответа клиенту, которая раньше находилась в контроллере, в блоке, передаваемому методу respond_to. Сейчас стало удобно контролировать отдачу типов контента - ну нужно править каждый метод контроллера, если вы захотите добавить или убрать тип контента. Кстати, метод respond_to поддерживает ключи :only и :except, чтобы контролировать типы контента для методов.
Самое главное - это все работает, и работает замечательно! Я сейчас пишу проект на Rails 3 и использую всю эту красоту. В общем - радости нет предела)

Рекомендую почитать вот эту статейку на английском: Controllers in Rails 3

Отличная презентация об улучшениях в коде проекта на Rails 3

Вторник, Август 31st, 2010

Смотрим, как нужно писать код теперь. Мне презентаха очень понравилась!

Installing Ruby 1.9.2 and Rails 3 stable on Ubuntu

Вторник, Август 31st, 2010

Let’s install Ruby 1.9.2 and Rails 3 stable on Ubuntu. I’m going to use just one Ruby version so, this installation without RVM (Ruby Version Manager). I’m using Ubuntu 10.04, 32 bit version.

If you have not yet installed the following packages - install them:

$ sudo apt-get install gcc g++ build-essential libssl-dev libreadline5-dev zlib1g-dev linux-headers-generic libsqlite3-dev

Now download Ruby 1.9.2 sources, unpack them and install:

$ wget ftp://ftp.ruby-lang.org//pub/ruby/1.9/ruby-1.9.2-p0.tar.gz
$ tar -xvzf ruby-1.9.2-p0.tar.gz
$ cd ruby-1.9.2-p0/
$ ./configure --prefix=/usr/local/ruby
$ make && sudo make install

Add path to binary Ruby files.

$ sudo gedit /etc/environment

You need to add in the PATH variable that path - /usr/local/ruby/bin, should look something like this:

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/ruby/bin"

Then run the source command for the file /etc/environment to apply changes.

$ source /etc/environment

Now check is Ruby installed properly:

$ ruby -v

You should see something like this: ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
Now create a symbolic link for ruby and gem program

$ sudo ln -s /usr/local/ruby/bin/ruby /usr/local/bin/ruby
$ sudo ln -s /usr/local/ruby/bin/gem /usr/bin/gem

Ruby 1.9.2 is already includes Rubygems, so you do not have to install it.
Now install the required gem packages, including Rails 3.:

$ sudo gem install tzinfo builder memcache-client rack rack-test erubis mail text-format bundler thor i18n sqlite3-ruby
$ sudo gem install rack-mount --version=0.4.0
$ sudo gem install rails --version 3.0.0

Check Rails version:

$ rails -v

You should see the version number 3.0.0. Otherwise, try to execute command source /etc/environment and enter rails -v command once again.
Now you are ready to create a new Rails 3 application:

$ rails new myproject
cd myproject
rails server

UP: To update rails to latest version (3.0.3 for now), run:

sudo gem update rails

And change rails gem in your Gemfile to gem ‘rails’, ‘3.0.3′

Установка Ruby 1.9.2 и Rails 3 stable на Ubuntu

Вторник, Август 31st, 2010

Давайте установим Ruby 1.9.2 и Rails 3 stable на Ubuntu. Я использовал Ubuntu 10.04, 32-х битную версию. Здесь рассматривается установка Ruby без RVM, так что если будете следовать этому мануалу, то сначала удалите старую версию Ruby и её зависимости.

Если у вас еще не установлены следующие пакеты - установите их:

$ sudo apt-get install gcc g++ build-essential libssl-dev libreadline5-dev zlib1g-dev linux-headers-generic

Теперь скачаем исходники Ruby 1.9.2, распакуем их и установим:

$ wget ftp://ftp.ruby-lang.org//pub/ruby/1.9/ruby-1.9.2-p0.tar.gz
$ tar -xvzf ruby-1.9.2-p0.tar.gz
$ cd ruby-1.9.2-p0/
$ ./configure --prefix=/usr/local/ruby
$ make && sudo make install

Добавим путь к бинарным файлам Ruby.

$ sudo gedit /etc/environment

Вам нужно добавить в переменную PATH этот путь - /usr/local/ruby/bin, должно получиться примерно так:

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/ruby/bin"

Затем выполним команду source для файла, чтобы применить изменения.

$ source /etc/environment

Теперь проверим, установился ли Ruby:

$ ruby -v

Вы должны увидеть примерно следующее: ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
Теперь создадим символическую ссылку, чтобы программа gem работала

$ sudo ln -s /usr/local/ruby/bin/ruby /usr/local/bin/ruby
$ sudo ln -s /usr/local/ruby/bin/gem /usr/bin/gem

Ruby 1.9.2 уже содержит Rubygems, поэтому вам не придется его устанавливать.
Теперь установим нужные пакеты gem, включая rails 3.:

$ sudo gem install tzinfo builder memcache-client rack rack-test erubis mail text-format bundler thor i18n sqlite3-ruby
$ sudo gem install rack-mount --version=0.4.0
$ sudo gem install rails --version 3.0.0

Проверим версию rails:

$ rails -v

Вы должны увидеть номер версии 3.0.0. Если этого не произошло, по попробуйте выполнить команду source /etc/environment, затем запустите rails -v еще раз.
Теперь всё готово к созданию нового приложения rails:

$ rails new myproject
cd myproject
rails server

Установка Ruby и RoR на Ubuntu 10.04

Среда, Август 18th, 2010

Если вы используете Ubuntu 10.04 или 9.10, то следующие шаги по установке будут одинаковы для той и другой версии ОС. Чтобы установить Ruby on Rails, сначала вам нужно установить некоторые примочки, а так же сам Ruby.

Можно установить Ruby из репозитория, либо из исходного кода. Чтобы установить Ruby из репозитория, наберите в терминале следующую строку:

$ sudo apt-get install ruby-full build-essential

Если же вы хотите установить из исходников, то сначала нужно установить следующие пакеты:

$ sudo apt-get install build-essential libssl-dev libreadline5-dev zlib1g-dev

Теперь вам нужно скачать архив с исходными кодами Ruby:

$ wget ftp://ftp.ruby-lang.org/pub/ruby/stable-snapshot.tar.gz

Разархивируем файлы:

tar xzf stable-snapshot.tar.gz

Компилируем и устанавливаем Ruby:

$ cd ruby/
$ ./configure
$ make
$ sudo make install

Теперь запустите в консоли команду irb, и если вы не увидите никаких ошибок - поздравляю, Ruby установился успешно.

Перед тем, как установить Rails, вам нужно установить некоторые пакеты gem. Gem-пакеты - это упакованные приложения или библиотеки Ruby. Вы можете использовать команду gem чтобы установить различные бесплатные библиотеки, включая и Rails. Подробнее о rubygems можно почитать в мануале.

Устанавливаем rubygems следующей командой:

$ wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.2.tgz
$ tar xzvf rubygems-1.3.2.tgz
$ cd rubygems-1.3.2
$ sudo ruby setup.rb
$ sudo ln -s /usr/bin/gem1.8 /usr/bin/gem

Теперь при помощи команды gem устанавливаем Rails:

$ sudo gem install rails

Эта команда установит последнюю версию Rails, но если вы хотите установить одну из предыдущих версий, например 2.2.2, то воспользуйтесь следующей командой:

$ sudo gem install –version = 2.2.2 rails

Делаем сервер разработчика Rails с использованием виртуализации

Пятница, Июль 3rd, 2009

Всем пламенный привет после небольшого моего отсутствия :)

Сразу с места в карьер: я все свои разработки пишу в основном в windows. Это, конечно имеет как ряд преимуществ (лично для меня), так и ряд неудобств.

Недавно мне пришла в голову идея - почему бы не сделать сервер разработки приложений при помощи виртуальной машины. А что - это удобно. Мы получим нативную среду для приложений и избавимся от многих неудобств.

И тогда я установил Kubuntu в виртуальной машине VirtualBox и установил там LAMP и Rails. Сейчас по-порядку расскажу, как все это сделать.

Итак - первое, что нужно сделать - это установить саму виртуальную машину. Я воспользовался VirtualBox, так как она легкая, удобная и к тому же бесплатная. Я не буду рассказывать как установить Kubuntu под VirtualBox - это легко и достаточно материалов по этой теме есть в интернете. (далее…)