Отблеск зари на жемчужине (язык Ruby)

СЕРГЕЙ КОЗЛОВ teleman@elnet.msk.ru

Бей красных, пока не побелеют, бей белых, пока не покраснеют.
Лозунг зеленых

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

В жизни мало знать только один язык, даже родной (например русский). Тем более это сложно в мире компьютеров. Конечно, вполне можно обойтись готовыми продуктами (программами) и достичь нужных результатов, всего лишь выдав последовательность мышиных кликов. Но рано или поздно осозна¬шь, что последовательности эти часто повторяются, что они, мягко говоря, раздражают, что постоянно встречаются простенькие задачки, для которых навороченные готовые продукты не нужны, и часто эти микрозадачки можно быстрее и изящнее решить, написав собственные микропрограммки.

То, что графический интерфейс стал доминирующим, привело к "незаметному", но очень важному, на мой взгляд, последствию. Данные (текст, картинки, звуки и т. д.) обрели видимые символы-манипуляторы и некий набор элементарных операций над ними. Но при этом формирование более сложных операций стало возможным двумя основными способами: поручить их создание программистам (в виде готовых программ) или воспользоваться мышкой и тупо нажимать. Обычно выбирают последний способ (по принципу наименьшего сопротивления). Да, да, это та самая командная строка, с которой так не хотят расставаться жители мира *nix. То, что язык командных файлов DOS был убог, неоспоримо. То, что Visual Basic for Applications есть в MS Office, тоже известно. Но то, что такой естественный в применении инструмент практически исчез с уровня операционной системы, - это беда, крайность современного графического интерфейса как парадигмы. И пока что-то не видно достойного графического эквивалента.

То, что в *nix так естественно, - это скриптовые языки, и несть им числа. То, что Сеть уравнивает операционные системы, тоже известный факт. Для сайтов в Сети приходится писать скрипты, например на языке Perl. Но тот же Perl можно использовать не только для Сети. Люди это быстро осознали и стали применять его в повседневной работе. Так, или примерно так, скриптовые языки стали мигрировать с *nix.

Когда речь идет о скриптовых языках программирования, важными (или важнейшими) критериями применения языка я бы назвал степень владения им, его выразительность и, в меньшей мере, быстродействие. Язык постоянного (повседневного) использования должен быть достаточно прост в изучении, его конструкции должны быть компактными, и при этом на нем нужно решать самые разнообразные задачи. Как и во многих случаях, язык - это результат некоего компромисса. Не удержусь, чтобы не процитировать Ларри Уолла (Larry Wall), создателя Perl: "Минимализм: вера, что "малое прекрасно". Парадоксально, если вы скажете что-нибудь на маленьком языке, результат будет большим, а если скажете на большом языке, результат будет маленьким. Выбирайте". Perl - язык очень выразительный, взгляните на эти две строки:

#construct regex on the fly to parse xml tags 
$tags{$_}="(.*)<" . $_ . ">\\s*(.*?)\\ s*</" . $_ . ">(.*)" foreach @_;

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

Еще один момент - то, что Клейтон Кристенсен (Clayton Christensen) назвал в своей книге "Дилемма инноватора" ("The Innovator's Dilemma") "подрывной технологией" (disruptive technology). Любой продукт, который достаточно популярен (стал мэйнстримом), со временем обрастает, как днище корабля, ракушками больших и малых усовершенствований, становится все более совершенным и изощренным, но в то же время все более сложным и распухшим, часто превращаясь в заложника принятых когда-то проектных решений, а также все более мощным, но сложным и дорогим (в разных смыслах) для простых задач. И тут в ослепительно белом фраке появляется новый, не обремененный подобным грузом продукт, который оказывается более дешевым, простым, удобным в использовании и "достаточно хорошим" решением для многих (причину для себя я формулирую как следствие закона Парето: 80% пользователей используют не более 20% возможностей). И лидер сменяется. Особенно эта ситуация характерна для мира компьютеров. Монти Мэнли (Monty Manley) заметил по этому поводу: "Ни одна полезная программа не становилась меньше со временем - программисты напирают на добавление новых фич, а не на устранение старых ошибок".

Так что же это все-таки за язык, Ruby? Своим именем он обязан драгоценному камню рубину (заметна параллель с Perl - жемчуг). Вот как описывает Ruby его создатель, японский программист Юкихиро Мацумото (Yukihiro Matsumoto): "Это мощный и динамический объектно-ориентированный язык с открытыми исходниками, который я начал разрабатывать в 1993 году. Ruby работает на многих платформах, включая Linux и многие реализации Unix, MS-DOS, Windows 9x/2000/NT, BeOS и MacOS.

Главная цель Ruby - эффективность разработки программ, и пользователи найдут, что программирование на нем эффективно и даже забавно. Этот язык хорошо приспособлен для таких проблемных областей, как обработка текста, программирование CGI (есть все, что нужно, включая классы работы с текстом, библиотеку CGI, интерфейс базы данных и даже eRuby, встроенный Ruby, и mod_ruby для Apache) и XML, программирование для сети (есть поддержка сокетов), приложения с графическим интерфейсом (есть интерфейсы Ruby/Tk и Ruby/Gtk), прототипирование и обучение программированию".

Ruby вобрал в себя черты Perl, Smalltalk, Lisp. Ruby - язык динамический, поскольку не использует статической информации о типах. Он подобен скриптовым языкам: быстрый цикл разработки (редактирование - запуск - редактирование) с использованием интерпретатора, но автор языка настаивает на том, чтобы его называли динамическим объектно-ориентированным языком, а не скриптовым. По его мнению, Perl и Python - "скриптовые языки, поддерживающие объектно-ориентированное программирование", а Ruby - "объектно-ориентированный язык, поддерживающий скриптовое программирование". Разница, может быть, и тонкая, но она есть.

В отличие от Perl, Ruby изначально был объектно-ориентированным языком; средства объектно-ориентированного программирования (ООП) не являются добавлением (в Perl начиная с версии 5.000 для поддержки ООП используются довольно искусственные конструкции, и есть ограничение "один класс - один файл"). Ruby использует меньше закорючек ($,@,% и т. п.), в нем меньше зависимости от контекста и меньше неявных преобразований типов, и поэтому программы Ruby представляются менее загадочными, чем программы Perl (см. пример выше в тексте). Ruby позволяет проще обращаться со сложными структурами данных. Большинство функций, аналогичных "перловым", собраны в библиотеки классов. Простые программы на Ruby часто выглядят как упорядоченные, упрощенные и более понятные программы Perl.

Для сравнения: Python (тоже объектно-ориентированный скриптовый язык) использует формирование структуры программы с помощью отступов, в нем отсутствует сборка мусора, и есть ряд не очень удачных решений. Ruby-программы часто существенно быстрее Python-эквивалентов, в частности, из-за использования кэширования методов в интерпретаторе Ruby.

Как говорит Мацумото, Ruby проектировался как "язык, более мощный, чем Perl, и более объектно-ориентированный, чем Python".

Ruby - чистый объектно-ориентированный язык с самого начала разработки. Чистый, потому что все переменные являются объектами и объединяются в классы (множественное наследование не поддерживается). Каждая процедура - метод некоторого объекта. Операторы - специальная форма вызова методов. Вот типичное объявление метода класса (класс Foo, метод foo):

class Foo 
def foo
print "foo method in Foo class\n"
end
end

А это создание экземпляра класса и вызов его метода:

f = Foo.new 
f.foo

Вот типичный цикл, который печатает числа от 0 до 9 ("10 раз делай..."):

10.times do |i| 
print i, "\n"
end

Обратите внимание на вызов метода times и отсутствие begin (его функцию выполняет do). Хотя этот цикл можно записать и так:

10.times {|i| print i, "\n" } 

Переменные снабжаются префиксами, определяющими область видимости (а не тип, в отличие от Basic). Например, var задает локальную переменную, $var - глобальную переменную, а Pi - константу.

Ruby поддерживает концепцию исключений и даже реализует многопоточность (в том числе под MS-DOS!). Встроена сборка мусора.

В Ruby реализована концепция итератора, вот пример:

[ 1, 2, 3 ].each {|item| print item } 

Здесь печатаются элементы массива [1, 2, 3]. Итератор each ("для каждого") позволяет осуществить доступ к массиву без знания метода доступа. Ruby позволяет также определить свой собственный итератор.

Автор рассматривает язык программирования как интерфейс пользователя и поэтому считает, что язык должен следовать принципам интерфейса пользователя: краткость (хороший слуга должен делать много работы в ответ на короткий приказ), последовательность (универсальный объектный подход и небольшой набор правил; простой язык, но не слишком простой), гибкость (язык - средство выражения мыслей, он должен не ограничивать, а помогать этому. Ruby состоит из неизменного маленького ядра - синтаксис - и произвольно расширяемых библиотек классов).

Из библиотек классов стоит упомянуть библиотеки для работы с матрицами, Unicode, CGI, Socket, HTTP, POP3, FTP, SMTP, GUI (Tk, Gtk), базами данных (PostgreSQL, Interbase, Oracle, MySQL и др.).

Написан Ruby на C, и есть доступный Ruby API, благодаря чему можно писать на C расширения в виде динамических библиотек. Так, для Windows есть win32ole.dll, позволяющая, например, ловко управляться с Excel через OLE Automation.

По быстродействию Ruby примерно в полтора раза хуже Perl и впятеро превосходит Python. Но в экспериментальной стадии находятся транслятор Ruby-to-C и компилятор с технологией JIT (just-in-time - компиляция на лету), так что в дальнейшем от программ на Ruby можно ожидать большей производительности.

В Японии Ruby сильно потеснил Python и Perl (а книга "Ruby the Object-Oriented Scripting Language" стала бестселлером) и начал распространяться по всему миру. Вобрав в себя достоинства других языков и учтя их недостатки, он может стать очень популярным. Я не думаю, что Ruby "погубит" другие языки (они всякие нужны), но выглядит он весьма достойным внимания.

Официальный сайт Ruby: www.ruby-lang.org/en. Там можно найти свежий дистрибутив (на момент написания статьи это тарбол стабильной версии ruby-1.4.5.tar.gz). Дистрибутив для Windows (www.sugihara.com/ruby/ruby140.exe) "весит" 1,2 Мбайт, то есть помещается на 3,5-дюймовую дискету (удивительно, как быстро мы от них отвыкли!), и включает, помимо интерпретатора и библиотек, руководство, FAQ и примеры использования. Неплохой обзор Ruby можно найти на сайте IBM (www-4.ibm.com/software/developer/library/ruby.html).

Ваши предложения и замечания ждем по адресу: tails@computerra.ru

Вход для пользователей