Ruby: cheatsheet для изучения. Часть 1

  • Tutorial
Еще когда учился в школе, и интересовался языками, я считал, что нужно покупать две книги по любому языку: первую — «для чайников» и вторую — «мастер». В первой нужно было прочитать все hints — а остальное пролистать, а вторая — настольная (сейчас ее заменил Google). И подход вполне работал. Теперь, с развитием интернета, такой формат куда-то улетучился, и при самостоятельном изучении нужно по крупицам собирать данные — все материалы либо уже «pro», либо наоборот — азы, без «самого сока» и многих на практике важных вещей, или же — все сразу и в кучу на >9999 страницах.

Это — статья-roadmap-cheatsheet для изучающих Ruby и Rails (Rails и Gems запланированы на вторую часть). Вместо того, чтобы рассказывать очередной how-to я постараюсь расписать все те вещи, которые, на мой взгляд, можно изложить кратко и емко, с упором на то, что программисту пришедшему с других языков и платформ может показаться не очевидным, антипоисковым и просто затратным по времени на изучение без подсказок — на остальное просто дам ссылки (и есть Google — но ведь не всегда, особенно в начале пути, очевидно что у него нужно спрашивать). Не смотря на то, что в природе существует множество туториалов/кастов/книг/чего угодно по чему угодно — именно такого формата мне самому всегда не хватает. И по сути, это те вещи, которые чаще всего рассказываю при вопросах «а как оно вообще?», «с чего начать?», «а как делается такая вот штука?», «а какой gem лучше?» — теперь буду кидать ссылку сюда) Кстати, пока работал над этой статьей на Хабре появилась похожая про Python — видимо, идея витает в воздухе.

Около Ruby - слухи, интриги, расследования
Сразу оговорюсь, что текст под этим спойлером отличается от основной «объективной» части статьи, т.к. здесь изложено мое личное мнение и впечатление.

Язык программирования — это не только синтаксис, сборщик мусора, не только парадигма языка, и даже не столько его философия, в первую очередь — это коммьюнити и та кодовая база, которую это коммьюнити создало. Особенно сейчас, в эпоху OpenSource. И тут у Ruby первый жирный плюс в карму. Одна из особенностей — во всем читается прагматичная лень, начиная c опциональности скобок при вызове методов и точек с запятой в конце строки, продолжая емким и выразительным синтаксисом, и заканчивая общим ощущением от проектов — многие из них сделаны работающими из коробки, и требующих минимальных усилий, чтобы сконфигурировать их.

Многие выбирают Ruby, потому что это комфортно и приятно. Удовольствие и радость от программирования можно получить на разных языках — и в Ruby оно похоже на езду на хорошем авто. Не на суперкаре, подвеска которого пересчитывает каждую колдобину, но зато все вокруг в восторге, не на вседорожнике, на котором если вдруг приспичит можно помесить грязь, не на «зажигалке», чтобы со всеми гоняться с перекрестка, и не малолитражке (зато дешево и экологично) — именно на хорошей достойной машине, сидя за рулем которой будешь думать не столько о дороге, сколько о более важных вещах, хотя бы о маршруте и конечной цели поездки. И слушать любимую музыку, конечно.
Или же, можно сказать, что программирование на Ruby похоже на игру в Lego (и это во многом благодаря Gems). Хотя кто-то любит сварку арматуры, а кому-то достаточно картона и клея.

Но аналогии аналогиями. Есть несколько утверждений, которые иногда можно встретить о Ruby и Rails — попробую внести в них ясность.

Известно утверждение о том, что Ruby медленный. И поспорить сложно, ведь Ruby интерпретируемый язык. И что характерно, чаще всего я это слышу от тех кто пишет (исключительно) на PHP, который тоже интерпретируем, и по скорости в синтетических тестах находится примерно на том же уровне. Скорее всего, это отголоски дурной славы старых версий. По факту, мне приходилось работать и с Rails и с Symfony2 — на реальных приложениях Rails быстрее при одинаковом уровне оптимизации (и в обоих правильное кэширование — залог успеха). Если нужна скорость и компактность в памяти — пишите на ассемблере используйте Node.js. Но парадокс в том, что на нем как раз часто пишут рубисты — когда это действительно оправданно. И дело тут вот в чем: важна не только скорость работы, но и скорость написания приложения. И Ruby, и все то, что можно найти на github всячески помогает достичь действительно высокой производительности программиста — в том числе и в возможностях оптимизации приложения. И не нужно забывать, что и главная нагрузка, и бутылочные горлышки, зачастую — это базы данных, а веб-приложения это всего-лишь прослойка бизнес-логики. А такая прослойка неплохо масштабируется.

Есть еще своеобразный миф про высокие зарплаты Ruby-разработчиков с одной стороны, с другой — что работы на Ruby мало. Обычно сравнивают с зарплатами со средней по рынку на PHP, и количеством работы на нем же. Средний уровень зарплат на PHP — это классическая «средняя зарп температура по больнице». Если же сравнить специалистов по Yii/Symfony/Zend и Rails (можно еще добавить Django на Python) — картина выйдет совсем другая, а именно: и зарплаты и объем рынка примерно одинаковы. Действительно, хорошим программистам неплохо платят. И более того, когда берешься за проект с нуля — зачастую выбор платформы за тобой и твоей командой, а не заказчиком/начальством.

Так что, есть множество прекрасных языков и фреймворков для написания веб-приложений, и Ruby с Rails не являются серебряной пулей, которая убьет всех зайцев кроликов-оборотней сразу. Просто, на мой взгляд, если брать совокупность важных критериев, а не пытаться выбрать по одному-двум из них, RoR набирает действительно много очков. В том числе и по зрелости — это уже давно не хипстерская платформа, в которой есть только потенциал, но еще и не старичок (а примеров и тех и других уйма). И старичком, я думаю, еще долго не станет, т.к. потенциал для роста и развития еще есть и у Ruby и у Rails — но это тема для отдельной статьи.

И конечно, несмотря на направленность статьи на Rails, и популярность именно этой платформы — Ruby это далеко не только Rails.

В любом случае, я убежден, что программист не должен сидеть в своем маленьком мирке того, за что ему сегодня платят зарплату. Ruby дает в этом смысле не только +1 язык в резюме, но и, за счет своей ооп-направленности и широким возможностям метапрограммирования, опыт, который пригодится на разных языках и платформах.

Язык Ruby: история становления и перспективы развития


Ruby



Начало
Как установить Ruby на #{ os_name }?

Сами ссылки:
  • Win. По той же ссылке можно найти DevKit, которой пригодится для работы с БД и установки Native Extensions
  • Rails Installer установит сразу Ruby + DevKit, Git, Rails, Bundler и SQLite, на Windows или MacOS. Ruby, правда, 1.9.3, а установщик с 2.0 еще в alpha. (по совету Jabher)
  • *nix — ищите в своих репозиториях, или legacy

Кроме того, есть такая штука как RVM. Она позволяет установить несколько версий Ruby на одной ОС и переключаться между ними. На старте в ней потребности нет, но бывает полезна, если уже есть несколько проектов на локальной машине или на сервере — обновляться на всех разом до новой версии сразу не особо здорово. Пока — просто имейте ввиду, что она есть.
Подробно про RVM на хабре.

Тут же стоит упомянуть про среду разработки. Я приверженец продуктов JetBrains, поэтому рекомендую RubyMine, но ввиду того, что продукт коммерческий кому-то может прийтись по вкусу свободная Aptana Studio. Если же приятнее пользоваться легкими текстовыми редакторами — синтаксис Ruby поддерживается многими.

Прямо в браузере в интерактивном режиме Ruby можно попробовать на tryruby.org

Все - объект
Включая числа, строки и даже nil — они все наследуются от класса Object. Можно у чего угодно вызывать методы вроде nil?, class, methods и respond_to?:
'Hello world'.class # String
nil.class # NilClass
String.class # Class
String.anc­estors # [String, Comparable, Object, Kernel, BasicObject]; массив предков класса
nil.nil? # true
Object.new.methods # вернет методы объекта класса Object; тут же видно как создается новый объект - тоже вызовам метода
nil.respond_to?('nil?') # true
По поводу последнего: это важно для утиной типизации.

Синтаксис и пудра
Ruby сильно приправлен «синтаксическим сахаром», благодаря которому зачастую не нужно городить кашу из различных скобок, точек с запятыми и прочего. А под ним — прост и логичен, и сохраняет парадигму «все — объект».
a == b # то же, что и
a.==(b) # то есть .==() - это метод

В вызовах методов, в if можно не ставить скобки, если нет неоднозначности
nil.respond_to?('nil?') # true
nil.respond_to? 'nil?' # true
# все однозначно:
if nil.respond_to? 'nil?'
  puts 'ok'
end
# тоже
if 10.between? 1, 5
  puts 'ok'
end
# а вот так получится не тот приоритет вызовов, поэтому нужны скобки
if 10.between?(1, 50) && 20.between?(1, 50)
  puts 'ok'
end

А еще — есть символы. По сути, символы — это неизменяемые строки. Например, они часто используются как ключи в хэшах.
a = :nil? # символ
b = 'nil?' # строка
nil.respond_to? a # true
nil.respond_to? b # true
# поиграемся
a == b # false
a.to_s == b && a == b.to_sym # true; символ и строка преобразуются друг в друга

С ними связано еще немного пудры:
a = {:key1 => 'value1', :key2 => 'value2'} # создаем хэш (ассоциативный массив)
a = {key1: 'value1', key2: 'value2'} # если ключи - символы, то можно так (Ruby >= 1.9.3)
Раз уж тема зашла:
a = ['value1', 'value2'] # это массив
s = 'String'
s = "Double-quoted #{s}" # "Double-quoted String" - это, думаю, ясно

И добьем тему припудривания немного уродливым, но зато удобным способом записи:
%w[value1 value2] # ["value1", "value2"] - тот же массив, что и выше
%i[value1 value2] # [:value1, :value2] - массив символов, (Ruby >= 2.0)
s = %q(String)
s = %Q(Double-quoted #{s})
%x('ls') # команда консоли
`ls` # то же самое
%r(.*) == /.*/ # true; два способа создать регулярное выражение

Кстати, в Ruby есть многим до боли знакомая точка с запятой — пригодиться она может чтобы записать несколько выражений в одну строку
a = 10; puts a # выведет в консоль 10
if nil.respond_to? 'nil?'; puts 'ok'; end # чтобы было понятно - так тоже можно
Но однострочные if лучше писать так
puts 'ok' if nil.respond_to? 'nil?'


Вводные статьи и доки
Стоит почитать В Ruby из других языков и Ruby за двадцать минут, ну а главный друг и помощник ruby-doc.org.
Лучше сразу посмотреть методы базовых классов (во всех — какие бывают each_ и to_).
String (тут — первым делом match, sub)
Array (map, join, include?)
Hash (has_key?, has_value?, merge)
Достаточно простые примеры разобраны в Покорим Ruby вместе! Капля первая Капля вторая Капля третья
Если хочется продолжения банкета: Интересный паблик с подборкой магии на Руби.

Классы, модули и метапрограммирование
Классы в Ruby вполне очевидны, но в возможностях работы с ними кроется вся сила и прелесть Ruby.
class Foo
  def bar
    10 # любой метод возвращает значение - результат выполнения последнего выражения
  end
  def baz(a)
    bar + 20
  end
end
puts Foo.new.baz(10) # 30

Module — к нему можно относиться и как к примеси, и как к пространству имен. Внезапно? По сути — это набор классов, методов и констант, и пользоваться им можно на свое усмотрение.
module B # как пространство имен
  class Foo
    # конструктор
    def initialize(k) @k = k end # запишем методы в одну строку
    def bar; @k + 20 end
  end
end
puts B.Foo.new(3).bar # 23
puts B::Foo.new(3).bar # 23; то же самое, но читается лучше

module C # как примесь
  def bar; @k + 25 end
end
class Foo
  include C;
  def initialize(k) @k = k end
end
puts Foo.new(3).bar # 28


В Ruby классы мутабельны, и их можно патчить после их создания. И тут будьте осторожны: здесь начинаются те самые возможности, при помощи которых можно «выстрелить себе в ногу» — так что, делая что-то подобное нужно всегда отдавать отчет: зачем, что получится, кто виноват и что делать и если что — виноваты сами.
class Foo
  def bar; 20 end
end
class Foo # патчим
  def baz; bar + 2 end
end
puts Foo.new.baz # 22
# или лучше - так: сразу понятно что это патч
Foo.class_eval do
  def bazz; bar + 3 end
end
puts Foo.new.bazz # 23
# но если нет на то веской причины - используйте примеси или наследование
class Boo < Foo
  def boo; bar + 2 end
end
puts Boo.new.boo # 22
# или же - можно пропатчить только объект, а не сам класс
a = Foo.new
a.instance_eval do # патчим объект
  def booo; bar + 3 end
end
puts a.booo # 23
puts Foo.new.booo rescue puts 'error' # error; кстати, так перехватываются ошибки
puts a.respond_to? :booo # true
puts Foo.new.respond_to? :booo # false
# или - патчим объект в более легком синтаксисе
def a.booboo
  bar + 4
end
puts a.booboo # 24
А что если сделать instance_eval для класса? Конечно же, добавятся статические методы.
class Foo
  def self.bar; 10 end # обычный статический метод
end
puts Foo.bar # 10
Foo.instance_eval do
  def baz; bar + 1 end
end
puts Foo.baz # 11
Играться с этим можно вдоволь, главное помните — берегите ноги.
class Foo
  def self.add_bar # добавим статический метод, который патчит класс
	self.class_eval do
	  def bar; 'bar' end
	end
  end
end
puts Foo.new.respond_to? :bar # false
class Boo < Foo # отнаследуемся
  add_bar # пропатчим
end
puts Boo.new.bar # bar

# а теперь все то же самое, но пропатчим уже существующий класс
Foo.instance_eval do
  def add_baz
    self.class_eval do
      def baz; 'baz' end
    end	
  end
end
class Baz < Foo
  add_baz
end
puts Baz.new.baz # baz

Как раз такой подход используется на практике — по сути, получается что-то вроде примеси, в которую можно передавать параметры. Это кажется магией, если не знать, как это делается. Патчить можно и базовые классы, особенно любимы Array и String — но всегда стоит подумать трижды, прежде чем начинать их мучить: одно дело методы вроде .blank? (его добавляет Rails: что-то вроде def blank?; nil? || empty? end), другое — когда код метода специфичен для проекта, тогда логично предположить, что он относится к каким-то классам внутри проекта.

По такому принципу работает, например accessor. Что мы сделаем, чтобы добавить публичный параметр в Ruby-класс?
class Foo
  def bar # геттер
    @bar # возвращаем параметр
  end
  def bar=(val) # сеттер
    @bar = val # присваиваем значение параметру
  end
end

Представляете так писать для десятка-другого параметров? В Ruby много кода по накатанному — смертный грех: DRY. Так что, можно сделать короче.
class Foo
  attr_accessor :bar, :baz # добавим сразу парочку атрибутов
  attr_reader :boo # только геттер
  attr_writer :booo # только сеттер
end


Готовы дальше? Тогда:
Вникаем в метаклассы Ruby
Metaprogramming patterns — про monkey patching, Reuse в малом — bang!, eval
Вникаем в include и extend

Аргументы методов
Ruby 2.0 поддерживает именованные аргументы методов:
# bar обязателен
# barr имеет значение по умолчанию 0
# baz - именованный аргумент со значением по умолчанию true
def foo(bar, barr = 0, baz: true)
  baz && bar + barr
end
p foo 1 # 1
p foo 1, 2 # 3
p foo 1, baz: false # false

В предыдущих версиях добиться такого же поведения можно, разбирая атрибуты:
def foo2(bar, *args)
  args
end
p foo2 1, 2, :baz => false # [2, {:baz=>false}]

def foo3(bar, *args)
  options = args.extract_otions! # именованные аргументы вырезаются из args
  p bar
  p args
  p options
end
foo3 1, 2, 3, :baz => false
# 1
# [2, 3]
# {:baz=>false}

Начиная с Ruby 2.1 появилась возможность добавлять обязательные именованные аргументы.
def foo4(bar, baz:); bar end
foo4 1 # ошибка
foo4 1, baz: 2 # 1


Замыкания и блоки
Некоторое недоумение поначалу вызывают блоки, замыкания и класс Proc — зачем столько всего? Вкратце — на самом деле, есть только Proc.
Подробно — ссылки внизу, а сейчас — на что стоит обратить внимание.
Первыми рассмотрим блоки. Блок — это просто кусок куда, и даже не объект, просто часть синтаксиса Ruby. Блок используется чтобы передать какой-то код в метод. И уже в методе он оказывается завернут его в класс Proc.
В разделе про классы и методы они уже использовались:
Foo.instance_eval do # передаем в метод instance_eval блок с определением метода
  def baz; bar + 1 end
end

Но возьмем более базовый пример, он же «как сделать foreach в Ruby»:
[1,2,3].each do |val|
  p val # кстати, p(val) - это shortcut для puts(val.inspect)
end # выводит 1 2 3

# то же, в одну строчку 
[1,2,3].each { |val| p val } # выводит 1 2 3
[1,2,3].each_with_index { |val, i| puts val.to_s + ' ' + i.to_s } # на заметку

Если же мы хотим передавать блок в собственный метод:
def foo
  puts yield # выполняем блок
  puts yield + yield # и еще, и еще выполняем
end
foo { 2 } # 2 4
def bar(&block) # или, если поменьше пудры
  puts yield block # выполняем блок
end
bar { 3 } # 3

Стоит отметить, что блок идет всегда последним параметром, и если нужно передать несколько блоков — нужно их передавать как обычные параметры, а значит создавать Proc.new, или lambda.

Из блока всегда получается объект класса Proc, но сам блок это часть синтаксиса: мы можем его передать в метод, где он станет Proc, мы можем его передать в конструктор Proc, или использовать lambda, но нельзя просто записать блок в переменную.
proc = Proc.new { |a| a - 1 } # через конструктор
p proc.call(10) #9
p proc.class # Proc
l = lambda { |a| a + 1 } # создаем лямбду
p l.call(10) #11
p l.class # Proc
new_l = ->(a) { a + 2 } # тоже лямбда (Ruby >= 2.0)
p new_l.call(10) #12


Различия в поведении Proc созданными разными способами есть, читаем статью.
Здесь замыкания и блоки в Ruby разобраны вдоль и попрек
На Хабре про блоки, про замыкания

Стиль
По поводу как принято писать в Ruby есть целый гайд на GitHub
Вкратце, frequently used:
  • Отступы в 2 пробела
  • Названия методов строчными буквами через подчеркивание: def method_name
  • Названия классов и модулей с больших букв: class ClassName
  • Если метод возвращает true/false, название должно заканчиваться на вопрос (тот же, nil?)
  • Если есть два метода, один из которых изменяет объект, а другой возвращает новый — первый оканчивается на '!' (например, методы downcase и downcase! для строки — первый вернет новую, а второй изменит саму строку)
  • Вместо if(!value) лучше использовать алиас unless(value)
  • Блок однострочный берется в скобки {… }, а многострочный — в do… end


RubyGems - пакетный менеджер
Мир Ruby, наверное, был бы совсем другим, если бы не RubyGems.
С ними процесс дополнения проекта библиотеками выглядит очень просто:
  • выбираем что нам нужно с rubygems.org (или через ruby-toolbox.com), например, json_pure — JSON парсер на чистом Ruby (без C)
  • вводим в консоли gem install json_pure
  • а в нашем rb-файле:
    require 'json/pure' # какой именно путь должен быть стоит в доках посмотреть, обычно на github


Для удобства управления зависимостями есть bundler:
  • gem install bundler
  • bundler init
  • в появившемся Gemfile вписываем зависимости:
    source 'https://rubygems.org'
    gem 'json_pure'
    
  • bundler install
  • И в своем rb-файле
    require 'rubygems'
    require 'bundler/setup'
    

В реальных проектах список зависимостей может разрастись на несколько экранов, поэтому при переносе проекта на сервер гораздо удобнее выполнять bundle install, чем вручную смотреть что нужно и для каждого гема выполнять gem install. Ну а в Rails bundler используется из коробки.

Сами Gems обязательно рассмотрю в статье про Rails.

RubyGems — подробно
Управляем версиями с помощью Bundler
Знакомство с Gem. Часть первая Часть вторая
Пишем свой первый gem
Делаем gem для RubyGems
Создание гемов — Руководство

Ruby и C
Далеко не последняя по важности возможность RubyGems — Native Extensions. Все просто — вместе с гемом может быть скомпилирован прилагающийся код на C и вызван из кода самого гема. Благодаря этому, среди них есть достаточно шустрые парсеры, можно установить JavaScript'овый V8 в виде гема, и много других вкусностей.

А это нужно просто иметь ввиду: Inline C, может пригодится. Если коротко — в коде Ruby можно исполнять код на C, что полезно, например, при реализации численных алгоритмов.

Введение в расширения Ruby на C
Ruby и C. Часть 1, Часть 2, Часть 3.

Потоки
Простой пример с потоком:
thread = Thread.new do # создается отдельный поток
  a = 0
  1000000.times { a+= 1 } # загружаем процессор на некоторое время
  puts a # вывод результата
end
puts 'thread started' # текст выводится сразу после запуска потока
thread.join # ожидание завершения работы потока

Код выведет в консоль «thread started 100000».

Более низкоуровневые fibers (волокна) предлагают немного другой синтаксис, позволяющий управлять последовательностью исполнения, а также имеют меньшие издержки по памяти и времени инициализации, чем threads.

fiber = Fiber.new do # создание нового волокна
  Fiber.yield "fiber 1" # управление возвращается в контекст
  'fiber 2' # возвращаемое значение
end

puts fiber.resume # запуск волокна
puts 'context'
puts fiber.resume # возобновление работы волокна

Код выведет «fiber 1 context fiber 2».

Про GIL и настоящую многопоточность
Ruby поддерживает многопоточность, и различные версии интерпретатора отличаются ее реализацией. GIL в основной ветке сводит распараллеливание вычислений на нет, но использование потоков в нем имеет смысл для реализации асинхронности. Самый простой пример: мы можем слушать пользовательский интерфейс, параллельно выполняя какие-то операции. Или можем отправить запрос к БД и ждать ответа в одном потоке, отправлять email в другом, и не дожидаясь завершения отправить ответ пользователю. Но в суммарном времени исполнения выигрыша не будет, т.к. фактически в каждый момент времени будет нагружаться только одно ядро.

Чтобы обойти это ограничение можно использовать версии без GIL — jRuby или Rubinius (и при этом помнить, что потокобезопасность в них существенно ниже — для нее и нужен GIL). Другой вариант — запускать несколько отдельных копий программы, или использовать UNIX-форки (естественно, пулом таких воркеров вполне можно управлять Ruby-скриптом).

Узнав все это начинающий рубист может прийти в замешательство (желая использовать всю мощь своего 48-поточного сервера без лишней головной боли). На практике реальная многопоточность не всегда нужна (а иногда — если и нужна, то когда-нибудь потом). Кроме того, для многих задач есть соответствующие gem'ы, реализующие разные подходы, в том числе готовые HTTP-серверы (которые будут рассмотрены в статье про gems) и асинхронные фреймворки.


GIL нужен для этого:
a = 0
threads = []
10.times do # создаем 10 потоков
  threads << Thread.new do # добавляем объекты потоков в массив
    100000.times { a+= 1 } # 100 000
  end
end
threads.each(&:join) # ждем завершения всех потоков
puts a # вывод результата

Код выведет 1 000 000 в MRI, и черт знает что (от 100 000 до 1 000 000) в jRuby и Rubinius.

Используем потоки в Ruby

Зоопарк версий
MRI (Matz's Ruby Interpreter) — основная ветка Ruby от его создателя Yukihiro Matsumoto, или просто, Matz. Реализована на C. Когда просто говорят «Ruby» обычно имеют ввиду ее. Начиная с версии 1.9 объединена с проектом YARV (Yet another Ruby VM). Одна из основных ее особенностей — так называемый GIL (Global Interpreter Lock), на Хабре про нее писали (с продолжением). Сейчас актуальная версия Ruby 2.0 UPD: вышел Ruby 2.1. Чего нам ждать от Ruby 2.1?

jRuby, который написан на Java и работает в JVM, и соответственно интегрируется с кодом на Java. К сожалению, версия языка отстает от MRI (сейчас реализован Ruby 1.9.3), но тот же Rails заводится на нем с пол оборота.

Rubinius, который основан на MRI, но использует потоки операционной системы, а так же по максимуму написан на самом Ruby. По версии обычно up do date.

Скорость всех трех реализаций относительно друг друга разнится от задачи к задаче, а по потреблению памяти из троицы самый прожорливый — jRuby.

MacRuby — работает в связке с Objective-C на LLVM, заменив тем самым более ранний проект RubyCocoa. Для разработки под iOS существует форк MacRuby — RubyMotion.

IronRuby — реализация на платформе .NET. На протяжении своей жизни то забрасывается, то снова возобновляется разработка.

Opal — транслятор Ruby в JavaScript. Но не надо ждать от него чего-то выдающегося, это не jRuby для Node.js — он просто дает возможность писать ваш jQuery-код на Ruby. Или Express-код под Node.js. В общем, вариация на тему CoffeeScript.

Ruby Enterprise Edition (REE) — Ruby на стероидах. Проект завершил свое существование, т.к. новые версии и без наркотиков неплохо бегают.

Можно упомянуть MagLev — специфическая версия, может пригодится для разворачивания облачной инфраструктуры.

Также интересен проект mruby, в котором участвует Matz. Это — встраиваемый Ruby. Проект еще не закончен, но весьма многообещающе выглядит. Так что, ждем ruby на Arduino. mruby-arduino. На нем же основан MobiRuby, предназначенный для разработки мобильных приложений.

Ну и на закуску, KidsRuby, по смыслу напоминающий старичка Logo.


upd:
learnxinyminutes.com/docs/ruby — примеры кода на Руби.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 22
  • +3
    Хорошее начинание, полностью поддерживаю)

    Набор подобных туториалов по разным языкам был бы очень полезен как для новичков, так и для бывалых.
    А то все помнить не возможно, лучше знать где найти.
    • +1
      Спасибо! Сам был бы рад много что посмотреть в таком формате.
    • +4
      … интегрируется с котом на Java.

      Это просто замечательная опечатка! Вы скрасили суровый четверг! =)
      • +1
        Спасибо, поправил. Видимо, что-то по Фрейду =)
      • 0
        Очень хорошо структурирована информация, спасибо. За 10 минут освежил все знания, что были по Ruby. Хотелось бы в таком формате и по Rails.
        • 0
          Спасибо, обязательно будет продолжение про Rails.
        • 0
          Кстати, про установку на винде или маке — я бы порекомендовал railsinstaller.org, который сразу ставит кучу всего хорошего, для легкого входа и rubyinstaller.org для использования в дальнейшем.
        • 0
          Меня до сих пор удивляет, почему разработка на Ruby — дроже PHP. В этом году для своих надобностей изучил Ruby, и пребываю в полном восторге от его элегантности и лаконичности. Раньше писал практически только на PHP, но сейчас вижу что код получается лучше, и быстрее процентов на 30%.

          Но когда для одного коммерческого проекта присматривался к разработчикам, то один и тот же проект на ruby всегда стоит дороже. :( Несправедливость какая-то. :)
          • +1
            Это связано с порогом вхождения, на PHP быстрее можно начать, есть хостинги, книги php за 4 часа и т.д. До сих пор не так просто найти виртуальный дешевый хостинг на котором сразу установлен Ruby, а PHP хостинги на каждом шагу. Сейчас немного сдвинулось все в этом плане. Но опять же на PHP уже прямо сейчас есть Joomla, Wordpress,… То есть продукты которые решают основные задачи пользователей, и люди начинают изучать PHP что бы немного подправить функционал.
            • 0
              Да, действительно. Хостинг руби практически не найти. Но будем надеяться, что со временем все изменится. :)
              • 0
                Heroku, EngineYard, Shelly Cloud, CloudFoundry, Cloud66+любой vps.
            • 0
              Вы работаете на руби и расстраиваетесь, что вам платят больше?) По-моему, всё справедливо. И далеко не факт, что в конечном счете разработка на рельсах будет стоить дороже.
              • 0
                Нет, пишу я для себя, басплатно. А так — я со стороны закачика выступаю, а не разработчика.
            • 0
              Не знаю как MacBook, но в Mac OS X 10.8-10.9 точно MacRuby в поставке не присутствует. MacRuby нужно ставить отдельно.
              Кроме изначальной идеи, RubyMotion ничего не использует от MacRuby. Там абсолютно два разных подхода, начиная от toolchain и заканчивая компилятором.
              • 0
                RubyMotion is based on the MacRuby project, an implementation of the Ruby language for OS X.

                На сайте RubyMotion

                Про MacOS, вероятно, ошибся, спасибо.
                • 0
                  Вы написали, что RubyMotion использует MacRuby, но это по факту не так. Лорент сам неоднократно упоминал, что у них разные подходы, базовая лишь идея. Посмотрите статью «Getting To Know RubyMotion With Laurent Sansonett»:
                  www.sitepoint.com/getting-to-know-rubymotion-with-laurent-sansonetti
                  • 0
                    RubyMotion is a fork of MacRuby

                    Из предложенной статьи.
                    Соглашусь, что говорить в таком случае, что «RubyMotion использует MacRuby» — весьма расплывчато, поправлю. Но это никак не тянет на то, что у них «базовая лишь идея».
              • 0
                Спасибо, перечитал всю информацию по метапрограммированию — переосознал свои ошибки :)
                • 0
                  Отличная статья! Люблю такие «шпаргалки». Залез и посмотрел быстро, что забыл.

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