Ruby

Материал из свободной русской энциклопедии «Традиция»
(перенаправлено с «Руби»)
Перейти к навигации Перейти к поиску
Ruby logo.png
Руби
Парадигма:
мультипарадигменный
Тип исполнения:
интерпретатор
Типизация:
строгая, динамическая
Дата появления:
1995
Разработчики:
Юкихиро Мацумото





Реализации:
Ruby, JRuby
Создан под влиянием:
Перл, Эйфель, Smalltalk, Ада, Dylan, Python, CLU, Лисп, C++, PHP
Повлиял на:
Groovy, Amber

Ру́би (англ. Ruby — «Рубин») — интерпретируемый язык высокого уровня для быстрого и удобного объектно-ориентированного программирования. Язык обладает независимой от операционной системы реализацией многопоточности, строгой динамической типизацией, «сборщиком мусора» и многими другими возможностями. Руби близок по особенностям синтаксиса к языкам Перл и Эйфель, по объектно-ориентированному подходу к Smalltalk. Также некоторые черты языка взяты из Python, Лисп, Dylan и CLU.

Кроссплатформенная реализация интерпретатора языка является полностью свободной, распространяется с открытыми исходными текстами, возможностью копирования и модификации[1]. Текущей является версия 2.1.3, вышедшая 19 сентября 2014.

История создания и развития[править | править код]

Файл:Rubylogo2.jpg
Вариации на тему англ. ruby — «рубин»

Создатель Руби — Юкихиро Мацумото (Matz) — интересовался языками программирования, ещё будучи студентом, но идея о разработке нового языка появилась позже. Руби начал разрабатываться 24 февраля 1993 года и вышел в свет в 1995 году. Название связано с языком Перл, многие особенности синтаксиса и семантики из которого заимствовано в Руби: англ. pearl — «жемчужина», англ. ruby — «рубин».

Целью разработки было создание «настоящего объектно-ориентированного», лёгкого в разработке, интерпретируемого языка программирования. Из письма автора[2]:

Ruby родился 23 февраля 1993 года. В тот день я беседовал со своим коллегой о возможности существования объектно-ориентированного сценарного языка. Я знал Перл (Perl4, а не Perl5), но он мне не нравился — был в нем некий привкус игрушечного языка (да и поныне есть). А объектно-ориентированный интерпретируемый язык казался многообещающим. В то время я знал Пайтон. Но он мне не нравился потому, что я не считал его настоящим объектно-ориентированным языком. Его OO свойства казались надстройкой над языком. Мне, как языковому маньяку и фанату объектно-ориентированного программирования с пятнадцатилетним стажем, очень, очень хотелось, чтобы был истинно объектно-ориентированный, простой в использовании язык. Я пытался найти такой язык, но его не было.

Тогда я решил его создать. Прошло несколько месяцев, прежде чем интерпретатор заработал. Я добавил в мой язык то, что мне хотелось — итераторы, обработку исключений, автоматическую сборку мусора. Затем я переорганизовал свойства Перла и реализовал их как библиотеку классов. В декабре 1995 года я опубликовал Ruby 0.95 в японских новостных группах. С тех пор появились сайты, списки рассылок. В списках рассылок идут жаркие обсуждения. Самый старый, ruby-list, сейчас содержит 14789 писем.

В Японии Руби стал популярным с момента появления первой общедоступной версии в 1995 году, однако наличие документации только на японском языке сдерживало его дальнейшее распространение. Лишь в 1997 году появилось описание Руби на английском языке, а в 1998 году открылся форум «ruby-talk». Это положило начало росту известности языка в остальном мире. Издано несколько книг на различных языках, в том числе на русском. Сейчас Руби входит в большинство дистрибутивов ОС Linux, доступен пользователям других операционных систем.

Философия[править | править код]

Мацумото, фанат объектно-ориентированного программирования, мечтал о языке, более мощном, чем Перл, и более объектно-ориентированном, чем Python. Основное назначение Руби — создание простых и в то же время понятных программ, где важна не скорость работы программы, а малое время разработки, понятность и простота синтаксиса.

Язык следует принципу «наименьшей неожиданности»: программа должна вести себя так, как ожидает программист. Однако, в контексте Руби это означает наименьшее удивление не при знакомстве с языком, а при его основательном изучении. Сам Мацумото утверждает, что целью разработки была минимизация неожиданностей при программировании для него, но после распространения языка он с удивлением узнал, что мышление программистов похоже и для многих их принцип «наименьшей неожиданности» совпал с его принципом.

Руби также унаследовал идеологию языка программирования Перл в части предоставления программисту возможностей достижения одного и того же результата несколькими различными способами. Люди различны, и им для свободы необходима возможность выбирать. «Я предпочитаю обеспечить много путей, если это возможно, но поощрять или вести пользователей, чтобы выбрать лучший путь, если это возможно»[3].

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

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

Семантика[править | править код]

Руби — полностью объектно-ориентированный язык. В нём все данные являются объектами, в отличие от многих других языков, где существуют примитивные типы. Каждая функция — метод.

Переменные Руби содержат не сами объекты, а ссылки на них. Присваивание — это не передача значения, а копирование ссылки на объект. Для программиста, привычного к распространённым гибридным языкам программирования, некоторые эффекты такого решения могут показаться неожиданными. Например:

a = "abcdefg"   =>   "abcdefg"
b = a           =>   "abcdefg"
b               =>   "abcdefg"
a[3] = 'R'      =>   "R"
b               =>   "abcRefg"

то есть при изменении значения переменной a неявно изменилось и значение b, так как они содержат ссылку на один объект. С другой стороны, это более логично, чем ситуация, когда для переменных разных типов присваивание действует по-разному (как, например, в Object Pascal).

Руби не поддерживает множественное наследование, но вместо него есть мощный механизм примесей (англ. mixin). Все классы (напрямую или через другие классы) выведены из класса Object, следовательно, любой объект может использовать определенные в нем методы (например, [[[:Шаблон:MakeRef]] class], [[[:Шаблон:MakeRef]] to_s], [[[:Шаблон:MakeRef]] nil?]). Процедурный стиль также поддерживается, но все глобальные процедуры неявно являются закрытыми методами класса Object.

Руби является мультипарадигменным языком: он поддерживает процедурный стиль (определение функций и переменных вне классов), объектно-ориентированный (всё — объект), функциональный (анонимные функции, замыкания, возврат значения всеми инструкциями, возврат функцией последнего вычисленного значения). Он поддерживает отражение, метапрограммирование, информацию о типах переменных на стадии выполнения.

Возможности Руби[править | править код]

  • Имеет лаконичный и простой синтаксис, частично разработанный под влиянием Ада и Эйфель.
  • Позволяет обрабатывать исключения в стиле Java и Python.
  • Позволяет переопределять операторы, которые на самом деле являются методами.
  • Полностью объектно-ориентированный язык программирования. Все данные в Руби являются объектами в понимании Smalltalk. Например, число «1» — это экземпляр класса Fixnum. Также поддерживается добавление методов в класс и даже в конкретный экземпляр во время выполнения программы.
  • Не поддерживает множественное наследование, но вместо него может использоваться концепция «примесей», основанная в данном языке на механизме модулей.
  • Содержит автоматический сборщик мусора. Он работает для всех объектов Руби, в том числе для внешних библиотек.
  • Создавать расширения для Руби на Си очень просто частично из-за сборщика мусора, частично из-за несложного и удобного API.
  • Поддерживает замыкания с полной привязкой к переменным.
  • Поддерживает блоки кода (код заключается в {} или doend). Блоки могут использоваться в методах или преобразовываться в замыкания.
  • Целые переменные в Руби автоматически конвертируются между типами Fixnum (32-разрядные) и Bignum (больше 32 разрядов) в зависимости от их значения, что позволяет производить целочисленные математические расчёты с бесконечной точностью.
  • Не требует объявления переменных. Язык использует простые соглашения для обозначения области видимости. Пример: просто var — локальная переменная, @var — переменная экземпляра (член или поле объекта класса), @@var — переменная класса, $var — глобальная переменная.
  • В Руби непосредственно в языке реализованы многие шаблоны проектирования, так, например, «одиночка» (singleton) может быть (хотя и не обязан) реализован добавлением необходимых методов к одному конкретному объекту (см. ниже).
  • Может динамически загружать расширения, если это позволяет операционная система.
  • Имеет независимую от ОС поддержку невытесняющей многопоточности.
  • Перенесён на множество платформ. Он разрабатывался на Linux, но работает на многих версиях Unix, DOS, Windows (в частности Win32), Mac OS, BeOS, OS/2 и т. д.

Примеры[править | править код]

В Руби есть немало оригинальных решений, редко или вообще не встречающихся в распространённых языках программирования. Можно добавлять методы не только в любые классы, но и в любые объекты. Например, вы можете добавить к некоторой строке произвольный метод.

                   # всё: от символа # и до конца строки — комментарий
                   # = является оператором присваивания,
                   # символы в «"» - строка, которой можно манипулировать средствами языка
  str = "Привет"   # здесь создаётся переменная str, типа [[строковый тип|String]]
                   # def - ключевое слово для объявления функции
  def str.bye      # str. указывает, кому принадлежит метод (по умолчанию Object)
                   # bye - имя метода, за ним может следовать необязательный, заключённый в
                   # круглые скобки список параметров функции
    "Пока!"        # из метода возвращается последнее вычисленное значение (здесь - строка)
  end              # ключевым словом end заканчиваются практически все инструкции Руби
                   # puts - метод,
                   # str.bye - обращение к методу bye объекта str
                   # значение, полученное из метода bye передаётся методу puts
                   # который выводит на экран информацию
  puts str.bye     #=> Пока!

Этот пример также демонстрирует, как в Руби можно использовать синглтон. В этом примере синглтоном является объект str.

Любая конструкция в Руби возвращает значение. Например:

                   # конструкция if вычисляет выражение после него, и, если оно истинно,
                   # возвращает результат выражения между then и else, иначе между else и end
  puts( if 5 > 3 then "Одно" else "Другое" end )   #=> Одно
                   # происходит присваивание значения переменной var, и операция присваивания
                   # возвращает значение переменной var, которая выводится на экран
  puts( var = 5 )                                  #=> 5

Контейнеры[править | править код]

Работа с массивами — одна из сильных сторон Руби. Они автоматически изменяют размер, могут содержать любые элементы и язык предоставляет мощные средства для их обработки.

                           # создаём массив
 a = [1, 'hi', 3.14, 1, 2, [4, 5] * 3]
                           # => [1, "hi", 3.14, 1, 2, [4, 5, 4, 5, 4, 5]]
                           # обращение по индексу
 a[2]                      # => 3.14
                           # «разворачиваем» все внутренние массивы, удаляем одинаковые элементы
 a.flatten.uniq            # => [1, 'hi', 3.14, 2, 4, 5]
                           # пытаемся найти индекс элемента со значением 4
 a.index(4)                # => nil
                           # предыдущая попытка найти элемент неудачна - все предыдущие функции
                           # возвращают копии, но Руби почти для всех функций предоставляется аналог
                           # с тем же названием, но заканчивающийся на «!»,
                           # который модифицирует контейнер
 a.flatten!                # => [1, "hi", 3.14, 1, 2, 4, 5, 4, 5, 4, 5]
 a.index(4)                # => 5

Процедурные объекты и итераторы[править | править код]

В языке есть 2 эквивалентных способа записи блоков кода:

 { puts "Hello, World!" }

 do puts "Hello, World!" end

Сопрограммы применяются с большинством встроенных методов:

 File.open('file.txt', 'w') { |file| # открытие файла «file.txt» для записи («w» - write)
   file.puts 'Wrote some text.'
 } # Конструкция устраняет неопределённость с закрытием файла: закрывается здесь при любом исходе

Следующий пример показывает использование сопрограмм и итераторов для работы с массивами, который показывает краткость записи на Руби многих достаточно сложных действий (случайно выбираем из последовательности квадратов чисел от «0» до «10» и распечатываем вместе с индексами):

 (0..10).collect{|v| v ** 2 }.select{ rand(2) == 1 }.each_with_index{|v,i| printf "%2d\t%2d\n", i, v }

Классы, примеси, методы, перегрузка операторов[править | править код]

Следующий пример определяет класс с именем Person, предназначенный для хранения информации о имени и возрасте некоторой персоны.

 class Person                # объявление класса начинается с ключевого слова class, за которым
                             # следует имя
   include Comparable        # [[b:Ruby/Справочник/Comparable|Comparable]] подмешивается к классу и добавляет
                             # методы <, <=, ==, >=, > и between?
                             # с использованием нижеопределённого
                             # в классе <=>
                             #
   @@count_obj = 0           # переменная класса для подсчёта числа созданных объектов
                             # 
                             # конструктор для создания объектов с помощью new
   def initialize(name, age) # name, age - параметры метода
                             # название переменных объекта начинается с @
     @name, @age = name, age # cоздаём объекты и увеличиваем счётчик на 1
     @@count_obj += 1
   end
              
   def <=>(person)           # переопределение оператора <=>
                             # (это даёт возможность использовать метод sort
     @age <=> person.age     # из метода возвращается последнее вычисленное выражение,
   end
  
   def to_s                  # для форматированного вывода информации puts
     "#{@name} (#{@age})"    # конструкция #{x} в 2-х кавычках замещается в Руби значением x
   end
  
   def inspect               # похож на to_s, но используется для диагностического вывода
     "<#{@@count_obj}:#{to_s}>"
   end
                             # пример метапрограммирования: добавляет методы для доступа к
                             # переменным объекта
   attr_reader :name, :age
 end
                             # создаём массив объектов
 group = [ Person.new("John", 20),
          Person.new("Markus", 63),
          Person.new("Ash", 16) ]
                      # => [<3:John (20)>, <3:Markus (63)>, <3:Ash (16)>]
                      # здесь при работе с irb автоматически вызывается метод inspect
                      # вызываем методы массива сортировка и разворачивание его в обратном порядке
 puts group.sort.reverse # Печатает:
                         # Markus (63)
                         # John (20)
                         # Ash (16)
                                    # обращаемся к функции, которая была добавлена
                                    # автоматически(используя <=>) при включении Comparable
 group[0].between?(group[2], group[1]) # => true

Исключения[править | править код]

Исключения возбуждается с помощью конструкции raise (или fail), опционально могут быть добавлены текст с сообщением, тип исключения и информация о стеке вызовов:

 raise ArgumentError, "Неверный аргумент", caller # caller - метод возвращающий текущий стек выполнения

Обрабатываются исключения с использованием конструкции rescue. Опционально можно указать тип обрабатываемого исключения (по умолчанию обрабатываются все) и получение информации. Также можно добавлять блоки else (выполняется если исключения отсутствовали) и ensure (выполняется в любом случае).

 begin
  # ...
 rescue RuntimeError => e
   # обрабатываем конкретный тип ошибок
 rescue
   # обрабатываем все исключения
 else
   # сработает если исключений не было
 ensure
   # сработает в любом случае
 end

Реализация[править | править код]

Для Руби существуют 2 основные реализации: официальный интерпретатор и JRuby — реализация для Java. Интерпретатор портирован под большинство платформ, включая Unix, Microsoft Windows, DOS, Mac OS X, OS/2, Amiga, BeOS, Syllable, Acorn RISC OS и другие.

Интерактивный Руби[править | править код]

С официальной версией интерпретатора Руби поставляется интерактивный интерпретатор языка. Запускаемый командой irb в консоли, он позволяет тестировать текст программы очень быстро (построчно):

 $ irb
 irb(main):001:0> "Hello, World"
 => "Hello, World"
 irb(main):002:0> 2 ** 256             # ** - оператор возведения в степень
 => 115792089237316195423570985008687907853269984665640564039457584007913129639936

Программа irb выводит результат каждой строки после символов =>. В приведённых выше примерах для наглядности применяется аннотирование — результаты строк программы записываются в комментариях после =>. Имитацию irb можно запустить непосредственно в браузере.

В поставке дистибутива One-Click Installer для Windows, начиная с версии 1.8.2-15, поставляется утилита fxri, которая включает в себя справочную систему (ri) и интерактивный интерпретатор (irb).

Поддержка IDE[править | править код]

Базовые возможности редактирования добавляются к многим редакторам (Emacs, vim, jEdit, nano, SciTE и др.), здесь перечислены только IDE, т.е. предоставляющие обширный набор функций.

Название Лицензия Платформы Ссылка
ActiveState Komodo Проприетарная Linux, Mac OS X, Solaris, Windows [1]
Arachno Ruby IDE Проприетарная Win 2000/XP, Linux [2]
Eclipse + RDT CPL Java [3] + [4]
Aptana (RadRails+RDT) CPL Java [5]
FreeRIDE Ruby License Windows, OS X, POSIX [6]
KDevelop GNU GPL Unix [7]
RDE Ruby License Windows [8]
NetBeans IDE(Version 6) CDDL Java [9]
Ruby in steel Проприетарная Visual Studio 2005 [10]

Библиотеки[править | править код]

Стандартная библиотека[править | править код]

Кроме мощных возможностей встроенных в язык, Руби поставляется с большой стандартной библиотекой. Это прежде всего библиотеки для работы с различными сетевыми протоколами на стороне сервера и клиента, средства для работы с различными форматами представления данных (XML, XSLT, YAML). Кроме встроенных в язык средств отладки, с Руби поставляются библиотеки для юнит-тестирования, профилирования. Работа с архивами, датами, кодировками, матрицами, OLE — неполный список того, что предоставляет стандартная библиотека.

Расширения[править | править код]

Файл:Rubylogo.png
Korundum и QtRuby — реализация привязки Руби к KDE и Qt

В языке Руби реализован простой и удобный механизм для расширения языка с помощью библиотек, написанных на Си, позволяющий легко разрабатывать дополнительные библиотеки[5][6].

Для унифицированного доступ к базам данных разработана библиотека Ruby DBI (поддерживает SQLite, Oracle, ODBC, MySQL, DB2, MS SQL, InterBase, ADO и др.). Также существуют библиотеки для конкретных баз данных, поддерживающих специфические для них операции.

Из графических библиотек следует отметить FxRuby — интерфейс к графической библиотеке FOX, графический пакет разработчика wxRuby (интерфейс к кросcплатформенному пакету wxWidgets на C++), QtRuby/Korundum — привязка к Qt и KDE соответственно, графические библиотеки для работы с Tk и Gtk. Также реализована библиотека для работы с OpenGL, позволяющая программировать трёхмерную графику.

Win32utils — позволяет обращаться к специфическим возможностям Win32 API. Rmagick — библиотека для работы с изображениями, поддерживающая более 90 форматов (основана на ImageMagick и GraphicsMagick).

Для управления библиотеками и программами Руби в виде самодостаточных пакетов предназначена система управления пакетами RubyGems[11] (англ. gems, gem — драгоценный камень).

Существует всемирный репозиторий программного обеспечения Руби RAA (Ruby Application Archive) [12]. Репозиторий по состоянию на март 2006 года насчитывает более тысячи проектов. Большое количество программного обеспечения, написанного на Ruby, пользуются хостингом проекта RubyForge[13], созданного специально с этой целью.

Файл:FreeRIDE-ss-05.jpg
FreeRIDE — IDE для Руби, реализованая с использованием библиотеки FxRuby.

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

Документация[править | править код]

Система RDoc предназначена для автоматического извлечения документации из исходных кодов и программ на Руби и её дальнейшей обработки. Является стандартом де-факто для подготовки документации по программному обеспечению, написанному на Руби.

Для доступа к документации Руби из командной строки Unix разработана программа ri. С её помощью можно получить информацию о модулях, классах и методах Руби. Онлайн-документация доступна на сайте http://www.ruby-doc.org.

Использование[править | править код]

Недостатки языка и интерпретатора[править | править код]

К недостаткам интерпретатора Руби сегодня можно отнести следующие:

  • Невысокая скорость работы (естественная расплата за быстрое написание сложных программ).
  • Отсутствие поддержки потоков операционной системы (для Unix-подобных операционных систем есть поддержка процессов ОС).
  • Отсутствие встроенной поддержки юникода в версиях до 1.8.x включительно (возможна работа с использованием дополнительных библиотек, добавлена в версиях 1.9.x).
  • Отсутствие компиляции в байткод. (При этом есть возможность компилировать Ruby в Java и .NET байткод, используя компилятор JRuby и Ruby.NET[7]). В версию 2.0 запланировано включение виртуальной машины YARV, компилирующей Ruby в байткод и существенно ускоряющей исполнение.

См. также[править | править код]

Примечания[править | править код]

  1. "LICENSE" (TXT). Retrieved 14 августа.  Unknown parameter |description= ignored (help); Unknown parameter |accessyear= ignored (help); Unknown parameter |lang= ignored (help); Check date values in: |accessdate= (help), "Лицензия Руби". Retrieved 14 августа.  Unknown parameter |description= ignored (help); Unknown parameter |accessyear= ignored (help); Check date values in: |accessdate= (help)
  2. Письмо Йокихиро Мацумото в рассылку ruby-talk ruby-talk:00382 от 4 июня 1999 года. Есть перевод всего письма на русский
  3. Интервью Юкихиро Мацумото(англ.)
  4. Из-за слабой документированности Руби в ранних версиях информация получена напрямую из исходников ("helium.ruby-lang.org/ftp/ruby". Retrieved 16 августа.  Unknown parameter |accessyear= ignored (help); Unknown parameter |lang= ignored (help); Check date values in: |accessdate= (help)). Указаны только стабильные (чётные) версии.
  5. Thomas, Dave. "Extending Ruby". Programming Ruby - The Pragmatic Programmer's Guide. Addison Wesley Longman, Inc. Retrieved 30 октября.  Unknown parameter |accessyear= ignored (help); Unknown parameter |lang= ignored (help); Check date values in: |accessdate= (help)
  6. Rooney, Garrett. "Extending Ruby with C". O'Reilly Media. Retrieved 30 октября.  Unknown parameter |accessyear= ignored (help); Unknown parameter |lang= ignored (help); Unknown parameter |datepublished= ignored (help); Check date values in: |accessdate= (help)
  7. "Ruby.NET". Queensland University of Tehnology. Retrieved 28 августа.  Unknown parameter |accessyear= ignored (help); Unknown parameter |lang= ignored (help); Check date values in: |accessdate= (help)

Ссылки[править | править код]

  • Ruby Home Page(русск.) — официальная страница на русском.
  • Ruby Home Page(англ.) — официальная страница.
  • RubyNews — новости для программистов на языке Ruby.
  • Форумы
  • Vingrad/Ruby — русскоязычный форум и wiki по Руби.
  • Документация, справочники, примеры и информация
  • Ruby.on-page.net(англ.) — самый простой справочник по Ruby
  • Ruby Documentation project(англ.) — документация по языку и библиотекам.
  • RubyGems(англ.) — основной менеджер пакетов программ Руби.
  • RubyGarden(англ.) — интересный блог.
  • Ruby on Rails на русском: Ruby — учебные статьи по Руби. На других страницах сайта есть статьи о RoR и других веб-технологиях.
  • PLEAC-Ruby(англ.) — примеры конструкций языка.
  • Full Ruby on Rails Tutorial
  • Программы
  • Ruby Application Archive(англ.) — программы написанные на Руби.
  • Реализации языка и расширения к нему
  • JRuby Home(англ.) — реализация интерпретатора Руби на Java.
  • RubyForge(англ.) — сайт расширений для Руби (аналог CPAN для языка Перл).
  • Книги
  • Крис Пайн /Chris Pine/ "Learn To Program" - полный русский перевод учебника.

Литература[править | править код]


Первоисточник этой статьи был признан «хорошей статьёй» русского раздела Википедии.

bat-smg:Ruby eo:Ruby (programlingvo) hu:Ruby programozási nyelv ia:Ruby (linguage de programmation) ka:რუბი (პროგრამირების ენა) ku:روبی lt:Ruby nn:Ruby ru-sib:Руби (перекатной говор)