Руби

Руби
Семантика: мультипарадигменный
Тип исполнения: интерпретатор
Появился в: 1995 г.
Автор(ы): Юкихиро Мацумото
Типизация данных: строгая, динамическая
Основные реализации: Ruby, JRuby
Диалекты: отсутствуют
Создан под влиянием: Перл, Эйфель, Smalltalk, Ада, Dylan, Python, CLU, Лисп
Оказал влияние на: Groovy, Amber

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

Кроссплатформенная реализация интерпретатора языка является полностью свободной, распространяется с открытыми исходными текстами, возможностью копирования и модификации[1]. Последней является версия 1.8.5, вышедшая 28 августа 2006.

Содержание

История создания и развития

Создатель Руби Юкихиро Мацумото (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].

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

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

Семантика

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

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

 irb(main):001:0> a = "abcdefg"   =>   "abcdefg"
 irb(main):002:0> b = a           =>   "abcdefg"
 irb(main):003:0> b               =>   "abcdefg"
 irb(main):004:0> a[3] = 'R'      =>   "R"
 irb(main):005:0> b               =>   "abcRefg"
 irb(main):006:0>

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

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

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

Возможности Руби

  • Имеет лаконичный и простой синтаксис, частично разработанный под влиянием Ада и Эйфель.
  • Позволяет обрабатывать исключения в стиле Java и Python.
  • Позволяет переопределять операторы, которые на самом деле являются методами.
  • Полностью объектно-ориентированный язык программирования. Все данные в Руби являются объектами в понимании SmallTalk. Например, число «1» — это экземпляр класса Fixnum. Также поддерживается добавление методов в класс и даже в конкретный экземпляр во время выполнения программы.
  • Не поддерживает множественное наследование, но вместо него может использоваться концепция «примесей», основанная в данном языке на механизме модулей.
  • Содержит автоматический сборщик мусора. Он работает для всех объектов Руби, в том числе для внешних библиотек.
  • Создавать расширения для Руби на Си очень просто частично из-за сборщика мусора, частично из-за несложного и удобного API.
  • Поддерживает замыкания с полной привязкой к переменным.
  • Поддерживает блоки кода (код заключается в {} или doend). Блоки могут использоваться в методах или преобразовываться в замыкания.
  • Целые переменные в Руби автоматически конвертируются между типами Fixnum (32-разрядные) и Bignum (больше 32 разрядов) в зависимости от их значения, что позволяет производить целочисленные математические расчёты с бесконечной точностью.
  • Не требует объявления переменных. Язык использует простые соглашения для обозначения области видимости. Пример: просто var — локальная переменная, @var — переменная экземпляра (член или поле объекта класса), @@var — переменная класса, $var — глобальная переменная. Таким образом нет необходимости использовать какой-либо специальный синтаксис (например, self.имя_переменной для Python) для доступа к переменным экземпляра.
  • В Руби непосредственно в языке реализованы многие шаблоны проектирования, так, например «одиночка» (singleton) может быть (хотя и не обязан) реализован добавлением необходимых методов к одному конкретному объекту (см. ниже).
  • Может динамически загружать расширения, если это позволяет операционная система.
  • Имеет независимую от ОС поддержку многопоточности.
  • Перенесён на множество платформ. Он разрабатывался на Linux, но работает на многих версиях Unix, DOS, Windows 95/98/Me/NT/2000/XP, 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        # 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, опционально могут быть добавлены текст с сообщением, тип исключения и информация о стеке вызовов:

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).

Библиотеки

Стандартная библиотека

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

Расширения

В языке Руби реализован простой и удобный механизм для расширения языка с помощью библиотек, написанных на Си, позволяющий легко разрабатывать дополнительные библиотеки[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[1] (англ. gems, gem — драгоценный камень).

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

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

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

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

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

Использование

  • RPG Maker — RGSS (Ruby Game Scripting System)
  • Amarok[4]
  • SketchUp — [5]
  • XChat
  • Для KOffice разрабатывается Kross[6], механизм для поддержки скриптов, который включает Руби [7].
  • WATIR[8] (англ. Web Application Testing in Ruby) - свободное средство для автоматического тестирования веб-приложений в броузере.

Недостатки языка и интерпретатора

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

  • Невысокая скорость работы (естественная расплата за быстрое написание сложных программ).
  • Отсутствие поддержки потоков операционной системы (утверждение действительно только для операционных систем семейства MS Windows, так как для Unix-подобных операционных систем есть Kernel.fork).
  • Отсутствие встроенной поддержки юникода (возможна работа с использованием дополнительных библиотек, планируется добавить в версии 1.9).
  • отсутствие компиляции в байткод. (При этом есть возможность компилировать Ruby в Microsoft .NET байткод, используя компилятор Ruby.NET[7])

См. также

  • Ruby on Rails — каркас для создания веб-приложений
  • JRuby — реализация Руби на Java и для Java
  • RubyGems — менеджер пакетов для Руби

Литература

Примечания

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

Ссылки

В Википедии есть портал Свободное программное обеспечение
В Викиучебнике есть материалы по теме Руби
В Викитеке есть материалы по теме Руби
  • Ruby Home Page(англ.) — официальная страница.
  • Ruby Application Archive(англ.) — программы написанные на Руби.
  • PLEAC-Ruby(англ.) — примеры конструкций языка.
  • RubyGarden(англ.) — интересный блог.
  • RubyForge(англ.) — сайт расширений для Руби (аналог CPAN для языка Перл).
  • Ruby Documentation project(англ.) — документация по языку и библиотекам.
  • JRuby Home(англ.) — реализация интерпретатора Руби на Java.
  • RubyGems(англ.) — основной менеджер пакетов программ Руби.
  • RubyNews — новости для программистов на языке Ruby.
  • RForum — русскоязычный форум посвященный Руби и Ruby on Rails.
  • Vingrad/Ruby — русскоязычный форум и wiki по Руби


Эта статья входит в число хороших статей русского раздела Википедии.
 
Начальная страница  » 
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ы Э Ю Я
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 Home