Перейти к содержанию

Ruby FAQ: различия между версиями

Материал из Викиучебника — открытых книг для открытого мира
Содержимое удалено Содержимое добавлено
Строка 12: Строка 12:


Отдельной строкой: [http://poignantguide.net/ruby/ Why’s (Poignant) Guide to Ruby]. Книга — шедевр, но на любителя.
Отдельной строкой: [http://poignantguide.net/ruby/ Why’s (Poignant) Guide to Ruby]. Книга — шедевр, но на любителя.

Для тех, кто интересуется не только синтаксисом: [http://mitpress.mit.edu/sicp/full-text/book/book.html Structure and Interpretation of Computer Programs aka "Wizard book"].


===Может мне кто нибудь кинуть ссылку от куда можно скачать "Мега книжку"?===
===Может мне кто нибудь кинуть ссылку от куда можно скачать "Мега книжку"?===

Версия от 07:49, 30 ноября 2007

Документация

Какие книги можете порекомендовать для изучения Ruby, Ruby on Rails?

Еще есть разные Ruby Recipes, Rails Cookbook и проч. На английском языке почти все из них съедобны, но второстепенны по отношению к упомянутым.

Отдельной строкой: Why’s (Poignant) Guide to Ruby. Книга — шедевр, но на любителя.

Для тех, кто интересуется не только синтаксисом: Structure and Interpretation of Computer Programs aka "Wizard book".

Может мне кто нибудь кинуть ссылку от куда можно скачать "Мега книжку"?

Не может. Ищите в гугле. В группе ror2ru уважают чужой интеллектуальный труд (как бы банально это ни звучало).

Есть какие либо бесплатные книги или документация в сети?

А где в Москве, Рязани, Казани найти книги на русском?

Есть нескольно относительно поганых переводов. Как показывает практика, проще выучить английский, чем искать перевод или, того хуже, местное творчество. Как бы прискорбно ни звучало.

(Ссылки на книги пишите здесь.)

Программирование на языке Ruby Идеология языка теория и практика применения - Фултон Х

Какие блоги почитать?

Ruby

Правда, что Ruby очень медленный язык?

Есть разные реализации языка Ruby. Самая широкоиспользуемая на сегодняшний день — MRI (Matz Ruby Interpreter) 1.8.6 является пока что и самой быстрой. Также существует реализация Ruby 1.9 (YARV), JRuby (Руби на чистой джаве), Rubinius (реализация по типу Smalltalk-80, с динамической оптимизацией), IronRuby (версия для дот-нета). Первые три реализации имеют задатки для реального ускорения относительно MRI 1.8.6, но фактически заметной оптимизации в них пока нет (1.9 все-такие реально быстрее процентов на 10, но менее стабильная).

Причины тормозов Ruby 1.8.6

  • Интерпретация, а не использование байт-кода. После загрузки файла, он раскладывается в AST (Abstract Syntax Tree), который интерпретируется рубином. Никакой оптимизации, по типу той, которую делают компиляторы Си или Джавы тут нет. Это основная причина тормозов языка.
  • Динамичность. В Си вызов функции — это одна машинная операция перехода по заранее известному адресу. В Ruby вызов метода — это посылка сообщения и поиск ответного метода. Методы в руби многократно дороже, чем даже виртуальные методы в Си++, но на порядок быстрее, чем общее время интерпретации синтаксиса (см. пред. пункт)

Так ли все плохо?

Да, Ruby медленнее чем Python, Perl, PHP, C, Java, Erlang. Но это не всегда критично.

Если рассматривать сетевые приложения, то получится, что большую часть времени программа проводит в ожидании ответа от сетевых устройств.

С другой стороны, бывают случаи, когда программа работает, скажем, в 100 раз медленнее, чем на Java, но она работает _достаточно быстро_ для имеющихся задач.

Кроме того, для рубина есть (и используются) удобные средства интеграции с Си, которые позволяют с легкостью выносить простые, но громоздкие для MRI задачи в Си и прикреплять с помощью динамических библиотек (.dll, .so, .bundle).

Есть примеры достаточно сложных и нагруженных систем, где работает Ruby.

(примеры в студию...)

Как исправляют?

В первую очередь, вносят компиляцию в байткод. Это происходит в YARV и в Rubinius. В JRuby такое пока планируется (поправьте, если не прав.). Байткод хорош тем, что он прост и его можно оптимизировать и даже компилировать прямо в машинный код, который останется лишь выполнить. Сложность заключается в том, чтобы сохранить динамику языка, поэтому эти системы не появляются за один день и существует немного примеров успешных реализаций (Smalltalk-80, Self-93, Strongtalk, как варианты).

Компенсация минусов MRI 1.8.x (Matz Ruby Interpreter)

Как преодолеваются различного рода проблемы.

  • Скорость интерпретатора. Особенно сказывается в коде, производящим вычислительную работу (смайлик). Если есть задача что-то посчитать, обработать строку, разобрать XML и т.п., то лучше всего написать для этого C-extension (расширение на Си). Как это делается см. в Pickaxe 2nd ed. или в первой редакции. API MRI позволяет писать на Си практически тот же код, что и на руби благодаря использованию родных рубиновых структур (RArray, RString и т.п.) Даже если переписать код впрямую на т.н. Ruby-C (Си с использованием руби-структур), будет достигнуто серьезно улучшение работы кода. Во-первых, благодаря тому, что не будет работать интерпретатор, во-вторых потому что вы будете использовать более эффективные примитивы (чистый int вместо Fixnum).

Иногда проще переписать имеющийся код на рубине так, чтобы его стало банально меньше. Так появился Merb, как альтернатива Rails. Основное его достоинство — в несколько раз меньшее время прохода запроса от сетевого порта до пользовательского кода ("время диспатча"). Если пользовательский код сам по себе очень быстр, то время диспетчеризации играет большую роль в общем быстродействии. Также Мерб умеет многопоточность, что позволяет сэкономить память, не запуская лишние экземпляры веб-серверов для максимальной утилизации CPU. Рельса же не является "thread-safe".

  • Утилизация 100% CPU, когда требуется 400%. В MRI используются «зеленые потоки» (green threads). Их достоинство — легковестность и большая скорость в сравнении с нативными потоками (уровня ОС), недостаток — утилизация только одного ядра, блокирование всех потоков на операциях ввода-вывода, блокирование всех потоков при выполнении native-кода (в экстеншенах). В случае серверного софта, следует проектировать программу так, чтобы её можно было запускать в раздельных процессах. Например, на четырех ядрах веб-сервер следует запускать как минимум в 4-х экземплярах и использовать балансирующий прокси-сервер для раздачи запросов между ними (например, nginx). Если веб-сервер не многопоточный, то количество экземпляров может быть и больше количества ядер (Рельса, например, не thread-safe, поэтому веб-сервер монгрел ставит все запросы к ней в одну очередь, блокируя мьютекс перед Dispatcher.dispatch!).
  • Блокирующий ввод-вывод. Существует библиотека EventMachine, которая избавляет от проблем с блокирующим вводом-выводом и предоставляет удобный унифицированный интерфейс для написания истинно event-driven приложений. Библиотека включает в себя реализации на чистом руби (не на всех платформах работает гладко), бандл на Си++ и версия для JRuby. Используется в проксирующем http-сервере Swiftiply.

Компенсация плюсов Ruby (бывает и такое)

Чрезмерное увлечение созданием DSL (domain specific language), неоправданное использование динамики. Речь идет о *_eval, .method_missing, .send. Общее правило: не следует делать реализацию более умной и сложной, чем того требует задача. Хорошая цитата со страницы о Мербе: «Be wary of clever code! Cleverness for cleverness sake is not our friend; if something is only slightly more handy but infinitely more complex, then please reconsider your implementation.»

Слишком «умный» код не только тяжел для понимания коллегами или самим писателем спустя некоторое время, но и приводит к ненужным затратам процессорного времени и оперативной памяти.

В частности DSL возникает когда становится очевидным некоторый паттерн. Пока вы не повторили некоторый код в точности пару-тройку раз, не имеет смысла его каким либо образом упаковывать в красивую оболочку метапрограммирования. belongs_to — это уже паттерн. Ваш код — еще нет.

Кодировки

  • Как успешно работать с Unicode? Уникод — слишком общее название. См. два варианта корректного вопроса:
  • Как успешно работать с кодировкой UTF-8? Читайте подробности ниже.
  • Как успешно работать с кодировкой XYZ? Хранить и обрабатывать данные в UTF-8, принимать и выдавать в той кодировке, которая нужна с помощью iconv (библиотека для одноименной программы).

Строки в руби не знают UTF-8?!

Строка в рубине по-определению — набор байт. Все операции типа string[0,3] управляют байтами, а не символами. Многие библиотеки рассчитывают работать с байтами, поэтому переопределение таких методов с тем, чтобы они понимали UTF-8 — неверный путь. В библиотеке activesupport существует модуль Multibyte (благодарности — Юлику Тарханову), которы добавляет к строкам метод chars, который является «прокси» для операций над utf-8-символами.

Чеклист

  • $KCODE = 'u'; require 'jcode' включает "юникод-режим" для ряда методов (они начинают работать с символами): chop!, chop, delete!,

delete, squeeze!, squeeze, succ!, succ, tr!, tr, tr_s!, и tr_s. Библиотека jcode довольно ограниченная. Рекомендуется использование activesupport и String#chars

  • require 'rubygems'; require 'activesupport'

Для рельсы:

  • в my.cnf (если у вас mysql) везде, где требуется, прописать utf8 (если, разумеется, есть доступ к нему).
  • в database.yml указать encoding: utf8
  • в каждой (!) миграции: create_table "some_models", :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8' (вместо InnoDB — ваш любимый тип таблиц)
  • в environment.rb — config.active_record.schema_format = :sql (потому что в schema.rb не сохраняются объявления кодировок — тесты будут поломаны)
  • mysqldump ... --default-character-set=utf8 ... — чтобы не получить черт-те что, если в my.cnf не прописано utf-8 в умолчальниях для базы и таблиц.

Ruby on Rails

Что такое EDGE и с чем его едят?

Едж — это по-английски "край". Последняя ревизия в репозитории. Когда говорят "сижу на едже", это означает, что используется не некоторая зафиксированная стабильная версия, а регулярное обновление библиотеки самыми последними ревизиями.

Репозиторий можно найти тут: http://dev.rubyonrails.org/

В первом утверждении есть доля лукавства. На самом деле, "стабильная ветка" тоже регулярно обновляется. Но туда не идут новые возможности — только исправления ошибок. Таким образом, едж — это свежий срез "девелоперской ветки".

Зачем

Едж хорош тем, что туда попадают разные полезные шутки, которые всем разработчикам сразу хочется использовать. Шутка. Некоторые важные исправления не всегда идут в обновление стабильных веток, но зато появляются в едже. Сейчас Core team достаточно организован, и код новой ревизии, как правило, не ломает серьезно ваше готовое приложение.

Если вы не покрываете свой код тестами на 99,99%, то использовать едж-рельсу вам будет очень страшно.

Как

Если вы держите свой репозиторий в subversion и хотите регулярно обновлять рельсу, вам пригодится Piston.

Если вы используете Git, то можете просто вычекнуть рельсу в vendor/rails или поступить хитрее — выделить её в отдельный репозиторий, обновлять там с помощью git-svn, а внутри своего репозитория подключить git-рельсу через git-submodules. (Спросите Юру yrashk Рашковского и Олега oleganza Андреева, как это делается :-)

Если вы хотите следить за изменениями по RSS, вам сюда: http://dev.rubyonrails.org/timeline/changeset — настраиваете что вам нужно и подписываетесь (внизу страницы). Если лень настраивать самому, в рассылке проскакивала такая ссылка: http://dev.rubyonrails.org/timeline?changeset=on&max=30&daysback=30&format=rss

Плагины

Плагин это механизм для расширения функциональности Rails фреймворка. Каждый плагин лежит в каталоге vendor/plugins и должен имееть init.rb файл, который подключится при запуске вашего Rails приложения.


Как установить плагин?

Можно просто использовать стандартный инструмент из Rails

ruby script/plugin install http://pluginrepo.com/plugin

Если вы используете svn, то можно добавить ключ -x, тогка плагин поставиться как svn-external. Таким образом, когда вы будете делать svn up, то плагины будут обновляться из внешнего репозитория.

Вообще это не удобно, поскольку нельзя гарантировать, что свежеобновленный плагин не поломает ваше приложение. От такой беды спасает инструмент Piston


Где найти нужный плагин для моего приложения?


Ресурсы, CRUD, REST

 * Слайды. 
 * Остальные части.

Средства разработки

Какие средства разработки на Ruby (и с поддержкой Rails) существуют?

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

IDE:

  • NetBeans - хорошая IDE, но для нормальной работы нужен большой компьютер.
  • IntelliJ IDEA
  • Aptana Studio

Часто используемые текстовые редакторы:

  • TextMate (Mac OS X only)
  • vim
  • emacs

От простых текстовых редакторов они отличаются в первую очередь тем, что у них есть бандлы к разным функциям Руби, Рельсы, РСпека. (Автозаполнение, запуск типичных скриптов.)

Самое главное: никто не продвигает никакое из средств написания кода как единственное верное. Если, скажем, среди IDE самая удобная — IDEA, это совершенно не волнует тех, кто пишет в TextMate-е. И уже тем более, тех, кто овладел таинством emacs (автор этих строк пишет в текстмейте и емакс еще не постиг).

Автор этих строк долгое время использовал совсем примитивный SciTE (и для руби, и для Си++ с джавой). Рубин позволяет писать код хоть на клочке бумаги. Это важное качество.

Тестирование

Какие средства для тестирования Ruby приложений существуют?

  • В стандартной поставке: require 'test/unit' (Test::Unit)
  • Чудо-библиотека для Behaviour Driven Development: RSpec (и "rspec on rails")