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

Материал из Викиучебника — открытых книг для открытого мира
Содержимое удалено Содержимое добавлено
+{{wikipedia}}
Строка 15: Строка 15:
|Абельсон и Сассман}}
|Абельсон и Сассман}}


{{wikipedia|Руби}}
'''Ру́би''' ({{lang-en|Ruby}}) — [[w:Интерпретатор|интерпретируемый]] [[w:Высокоуровневый язык программирования|язык высокого уровня]] для быстрого и удобного [[w:объектно-ориентированное программирование|объектно-ориентированного программирования]]. Язык обладает независимой от [[w:операционная система|операционной системы]] реализацией [[w:Многопоточность|многопоточности]], строгой [[w:динамическая типизация|динамической типизацией]], [[w:Сборщик мусора|«сборщиком мусора»]] и многими [[w:Руби#Возможности Руби|другими возможностями]]. Был задуман японским программистом Yukihiro Matsumoto (в сети известным под ником Matz), в 1993 году как результат синтеза всех лучших черт языков программирования с целью максимально упростить создание программ и сделать код элегантным и легко читаемым.
'''Ру́би''' ({{lang-en|Ruby}}) — [[w:Интерпретатор|интерпретируемый]] [[w:Высокоуровневый язык программирования|язык высокого уровня]] для быстрого и удобного [[w:объектно-ориентированное программирование|объектно-ориентированного программирования]]. Язык обладает независимой от [[w:операционная система|операционной системы]] реализацией [[w:Многопоточность|многопоточности]], строгой [[w:динамическая типизация|динамической типизацией]], [[w:Сборщик мусора|«сборщиком мусора»]] и многими [[w:Руби#Возможности Руби|другими возможностями]]. Был задуман японским программистом Yukihiro Matsumoto (в сети известным под ником Matz), в 1993 году как результат синтеза всех лучших черт языков программирования с целью максимально упростить создание программ и сделать код элегантным и легко читаемым.



Версия от 17:36, 27 мая 2006

Посвящаем созданную этим текстом заслугу благу всех живых существ.

Ом мани падме хум.

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

Йокихиро Мацумото (Matz)

Я хочу, чтобы компьютер был моим слугой, а не господином, поэтому я должен уметь быстро и эффективно объяснить ему, что делать.

Йокихиро Мацумото (Matz)

Программы должны быть написаны так, чтобы их могли читать люди, и только иногда так, чтобы их могли выполнять машины

Абельсон и Сассман

Ру́би (англ. Ruby) — интерпретируемый язык высокого уровня для быстрого и удобного объектно-ориентированного программирования. Язык обладает независимой от операционной системы реализацией многопоточности, строгой динамической типизацией, «сборщиком мусора» и многими другими возможностями. Был задуман японским программистом Yukihiro Matsumoto (в сети известным под ником Matz), в 1993 году как результат синтеза всех лучших черт языков программирования с целью максимально упростить создание программ и сделать код элегантным и легко читаемым.

Ниже приведен перевод письма Маца в список рассылки ruby-talk (ruby-talk:00382). Письмо датировано 4 июня 1999 года:

"Ruby родился 23 февраля 1993 года. В тот день я беседовал со своим коллегой о возможности существования объектно-ориентированного скриптового языка. Я знал Perl (Perl4, а не Perl5), но он мне не нравился -- был в нем некий привкус игрушечного языка (да и до сих пор есть). А объектно-ориентированный интерпретируемый язык казался многообещающим. В то время я знал Python. Но он мне не нравился, так как я не считал его настоящим объектно-ориентированным языком. Его OO-свойства казались надстройкой над языком. Мне, как языковому маньяку и фанату объектно-ориентированного программирования с пятнадцатилетним стажем, очень, очень хотелось, чтобы был истинно объектно-ориентированный, простой в использовании язык. Я пытался найти такой язык, но его не было. Тогда я решил его создать. Прошло несколько месяцев, прежде чем интерпретатор заработал. Я добавил в мой язык то, что мне хотелось -- итераторы, обработку исключений, автоматическую сборку мусора. Затем я реорганизовал свойства Perl'а и реализовал их как библиотеку классов. В декабре 1995 года я опубликовал Ruby 0.95 в японских новостных группах. С тех пор появились сайты, списки рассылок. В списках рассылок происходят жаркие дискуссии. Самый старый, ruby-list, сейчас содержит 14789 писем."

День рождения Ruby уточнен в письме ruby-list:15977 (правда на японском). Из него становится ясно, что днем рождения Ruby следует считать 24 февраля 1993 года.

Основные концепции языка программирования Ruby

Интерпретируемый скриптовый язык:

  • возможность прямого осуществления системных вызовов;
  • мощная поддержка операций со строками и регулярными выражениями;
  • немедленная обратная связь во время разработки;
  • отсутствие стадии компиляции;

Простое и быстрое программирование:

  • отсутствие необходимости объявления переменных;
  • переменные не типизированы;
  • простой и последовательный синтакс;
  • автоматическое управление памятью.

Объектно-ориентированное программирование:

  • все является объектом (даже имя класса является объектом класса Class);
  • классы, наследование, методы и т.д.
  • singleton-методы (методы, которые назначаются отдельному объекту, а не классу);
  • примеси (mix-ins) при помощи модулей (возможность нарастить функционал класса без наследования);
  • итераторы и скобочные операции.

Приятные моменты:

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

Обращение к читателям

Данный учебник построен по принципу спирали. Будут рассматриваться одни и те же темы несколько раз, но с разной степенью детализации. Первые главы будут специально лишены деталей для простоты восприятия. Учебник не претендует на полноту, поэтому, если вам необходимо более углубленное ознакомление с языком, то рекомендуем вам книгу ”ProgrammingRuby” Dave Thomas, которая пока не переведена на русский язык (хотя многие пытались). Первая редакция данной книги идет в составе дистрибутива One-Click Installer для Windows. Счастливые обладатели других ОС, могут найти ее на бескрайних просторах сети Интернет (в формате HTML-online). Вторую редакцию книги можно купить на Amazon.com (в формате PDF или «бумажном»).

Установка

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

Базовые знания

Для того, чтобы освоить материал данной книги, от вас потребуются базовые навыки работы с компьютером, а именно:

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

Имейте ввиду, что офисные пакеты (MS Office, OpenOffice.org, StarOffice и им подобные) в программировании вам не помогут. Программы набираются в простых текстовых редакторах типа Vi и Emacs . Хорошо, если вы знаете, что такое двоичный код и умеете переводить числа из одной системы исчисления в другую, всему этому обычно учат в школьных курсах информатики. Я советую использовать для разработки один из дистрибутивов Linux (Debian, Ubuntu, Slackware, OpenSuSE) и FreeBSD используя их вы получите мощную, стабильную платформу + знания которые часто оказываются необходимы для web-разработчика. Тем не менее, Ruby имеет реализации под все самые распространенные платформы: Windows, UNIX (GNU/Linux, FreeBSD, OpenBSD и др.) и даже для Mac OS X. Более того, программы, написанные в одной операционной системе, будут успешно выполняться в любой другой при наличии установленного интерпретатора Ruby! Ruby входит в комплект поставки большинства дистрибутивов GNU/Linux, но не факт, что это последняя версия. Поэтому стоит все-таки заглянуть на страницу Ruby и ознакомиться с новостями. Ruby, как и большинство проектов сообщества OpenSource, развивается очень динамично. Настоятельно рекомендуем пользоваться самым последним интерпретатором Ruby, ведь как говориться : "Там исправленны все обнаруженные ошибки и добавлено много новых". ;-) Теперь рассмотрим более подробно процесс установки интерпретатора Ruby в различных операционных системах.

Примечание: скорее всего, вам вообще не потребуется скачивать и устанавливать интерпретатор Ruby, если вы являетесь счастливым обладателем дистрибутива GNU/Linux или ОС *BSD.

Установка интерпретатора Ruby в OC Windows

Скачайте One-Click Installer для Windows c домашней странички проекта [1], размер файла с расширением .exe около 22Мб (для версии 1.8.4-17). Это комплексное решение содержащее в своем составе FreeRIDE, RubyGems, SciTE, примеры и многое другое. Кликните необходимое количество раз :-) и выберите компоненты для установки.

Установка Ruby интерпретатора в GNU/Linux

Для начала вы можете проверить, установлен ли у вас Ruby. После символа подсказки в командной строке (он обозначен здесь как "#", так что # набирать не надо), введите :

# ruby -v

Опция -v дает указание интерепретатору вывести его версию, затем нажмите кнопку Enter. Если Ruby установлен, вы увидите нечто похожее на:

# ruby -v
ruby 1.8.2 (2004-08-24) [i586-linux]

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

Для RPM-based дистрибутивов подходящий RPM пакет вы сможете обнаружить используя ресурс [2]. Вы сможете выбрать дистрибутив GNU/Linux, архитектуру, номер версии. Для примера, ruby-1.8.2.i386 - бинарный дистрибутив Ruby 1.8.2 для архитектуры Intel x86. Причем в RPM-based дистрибутивах GNU/Linux (RedHat Linux, Mandriva, SuSE Linux, ASPLinux, ALTLinux) рекомендуется устанавливать Ruby именно из rpm. Скачайте дистрибутив Ruby и установите его соответствующим образом. Для этого Вам потребуются права суперпользователя (root). Если вы вошли в систему в качестве непривилегированного пользователя, то перейдите в режим суперпользователя. Затем перейдите в папку, к которой находится rpm-пакет и наберите команду (с учетом того, какую именно версию Ruby вы скачали):

# rpm -i ruby-x.x.rpm

Для Debian dpkg-based GNU/Linux дистрибутивов, вы можете использовать знаменитый APT для поиска и установки интерепретатора Ruby. Используйте apt-cache следующим образоим (выполняем поиск):

# apt-cache search ruby interpreter
libapache-mod-ruby - Embedding Ruby in the Apache web server
liberb-ruby1.6 - Tiny eRuby for Ruby 1.6
liberb-ruby1.8 - Tiny eRuby
ruby - An interpreter of object-oriented scripting language Ruby
ruby1.7 - Interpreter of object-oriented scripting language Ruby
ruby1.8 - Interpreter of object-oriented scripting language Ruby

Вы можете установить любой из найденных пакетов используя apt-get следующим образом :

# apt-get install ruby1.8
Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
libruby1.8 Suggested packages:
ruby1.8-examples The following NEW packages will be installed:
libruby1.8 ruby1.8

Если у вас Gentoo Linux, то Ruby уже, скорее всего, будет установлен. Если же нет, то это досадное недоразумение исправляется очень легко, oписание последующих действий взято из статьи Александра Неткачева "Быстрый курс Ruby":

# emerge ruby

Далее можно переходить к установке дополнительных модулей или к первым программам на Ruby.Для Ruby есть большое количество различных библиотек и расширений. Доступные в Gentoo Linux можно посмотреть с помощью :

# emerge -s ruby

Кстати, если вы регулярно обновляете Portage, то, возможно, mod_ruby можно уже установить через "emerge mod_ruby". В моей версии его статус еще Masked.


Установка из исходного кода

Интерпретатор Ruby принадлежит к Open-Source категории ПО и вы можете самостоятельно собрать дистрибутив Ruby. Необходимый тарбол вы можете обнаружить на [3] , и распаковать командной tar :

# tar xzf snapshot.tar.gz
ruby/
ruby/bcc32/
ruby/bcc32/Makefile.sub
ruby/bcc32/README.bcc32


Прочитаем файл README и если там не указанны особые параметры совершим единое для всех POSIX-систем и древнее шаманство ./configure, make, make test, and make install. Если система не ругнулась и не выкинула в консоль предупреждений то инсталляцию можем считать оконченной. В большинстве систем сборку программного обеспечения рекомендуется производить в папке /usr/local/src/ .

Начинаем программировать

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

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

% ruby TecToBa9_nporpamma.rb

Специфика запуска программ на ОС Windows

Обладатели ОС семейства Windows могут не производить вышеописанные операцию (хотя команду cmd ни кто не отменял), а просто щелкнуть дважды по ярлыку с именем TecToBa9_nporpamma.rb. Помимо этого, любой редактор из стандартной поставки (SciTE и FreeRIDE) с радостью запустит вашу программу клавишей F5.

Специфика запуска программ на ОС *nix

Для ОС семейства UNIX'овых уже давно существует великое множество скриптовых языков. И все они имеют возможность запуска, без явного указывания интерпретатора в командной строке. Примерно вот так:

% ./TecToBa9_nporpamma.rb

Для того, чтобы эта команда сработала, необходимо вставить специальную строку в текст скрипта. В ней будет указан путь к интерпретатору, который будет обрабатывать данный скрипт. Чаще всего эта спецаильная строчка будет выглядеть так:

#!/usr/bin/ruby -w

Значки #! -- говорят о том, что этот файл является скриптом и дальше пойдет путь к интерпретатору. Строчка /usr/bin/ruby -- это путь к интерпретатору. Если интерпретатор находится у вас в другом месте, то просто измените эту строку. Опция -w приказывает интерпретатору выводить не только результат вычислений и сообщения об ошибках, но и предупреждения (w -> warning -> предупреждение).

Но это еще не все. Необходимо сообщить командной оболочке, что данный файл является скриптом и его можно запустить. Делается это командой chmod:

% chmod +x TecToBa9_nporpamma.rb

Вот и все. Дальше скрипт можно запускать либо двойным кликом ("Шурик, но это же не наш метод!"), либо способом, описанным ранее:

% ./TecToBa9_nporpamma.rb

Наша первая программа

Открываем текстовый редактор (Vim, Emacs, SciTE, FreeRIDE и т.д.) и начинаем писать нашу первую программу. По традиции это должна быть программа "Привет Мир!". Не будем ее нарушать:

puts "Привет Мир!"

Сохраняем ее с именем npuBeT_mup.rb и запускаем. На экране будет красоваться надпись:

Привет Мир!

На этом традиционную часть можно считать выполненной.


Типы данных

Все типы данных в Ruby -- это объекты тех или иных классов. Самые используемые встроенные типы данных: Fixnum (целые числа, меньшие ), Bignum (целые числа, большие ), Float (числа с плавающей точкой), Array (массивы), String (строки), Hash (ассоциативные массивы). Естественно, что это только базовые типы, но их вполне хватает для широкого спектра задач.

Числа

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

5     # целое число
-12   # отрицательное целое число
4.5   # число с плавающей точкой
076   # восьмеричное число
0b010 # двоичное число
0x89  # шестнадцатиричное число

Не будем пока углубляться и мельком взглянем на другие типы данных.

Массивы

Разработчики языка Ruby решили не реализовывать специальных классов для динамических массивов, списков, стеков и т.д. Они все это реализовали в массивах. Сделано это путем добавления специальных методов (например, методы .push и .pop для стека). Особенности массивов в языке Ruby:

  • нет ограничений (это общая философия Ruby). Массивы могут быть сколь угодно большого размера.
  • динамичность (размер массива легко меняется). Для того, чтобы узнать текущий размер массива, частно приходится пользоваться методом .size.
  • гетерогенность (один массив может хранить данные разных типов). Эта возможность позволяет использовать массивы в качестве структур.
  • огромная библиотека итераторов (на каждый случай жизни можно найти необходимый итератор). Эта возможность позволяет не использовать циклов для обработки данных в массивах, а следовательно избегать множества ошибок, связанных с неосторожным обращением с циклами. Реализация итераторов находится на высочайшем уровне.
  • огромное количество методов (практически все элементарные задачи по программированию решаются путем вызова того или иного метода). Например, для поиска максимального элемента достаточно вызвать метод .max, для сортировки массива -- .sort, для изменения порядка элементов на обратный -- .reverse.
  • конкатенация массивов выполняется методом +.

Массивы обычно начинаются [, а заканчиваются ]. Все предельно просто. Примеры массивов:

[1,2,3,4,5]       # целочисленный массив
["a","6","Br"]    # массив строк
[[1,2],[3,4]]     # двумерный массив
[1,"2",[3,4]]     # смешанный массив

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

Строки

Строки обладают используют общирные наработки языка Perl (но об этом речь пойдет в далеком будущем) для работы с текстом. Формально, строка -- это упорядоченная группа символов расположенная между парами кавычек. На практике это не всегда выполняется (как и в Perl, в Ruby можно выбирать ограничительный символ). Вот небольшой список возможностей строк:

  • нет ограничений. Длина строки может достигать поистине фантастических размеров (возможно использование строки размером более 1 Гб);
  • динамичность. Строки можно расширять или уменьшать (для этого есть методы + и []);
  • любой объект преобразуется к строке (методы .inspect и .to_s есть у любого объекта);
  • строка обладает обширной библиотекой методов, которые работают с правилами (это методы .gsub, .match, .scan, .split). Правила -- это новое название регулярных выражений. В текущей версии Ruby они называются регулярными выражениями, но давайте смотреть в будущее. Perl 6 уже не имеет понятия "регулярное выражение", заменив его "правилами" и "грамматиками";
  • существует возможность вставки произвольного кода на языке Ruby в строку. После его выполнения, результат будет вставлен на место кода;
  • конкатенация строк выполняется методом +. Многие методы массивов есть и в строках. Например, метод .reverse.

Строки обычно начинаются и заканчиваются кавычками (двойными или одинарными). Пример:

"мама мыла раму"        # строка в двойных кавычках
'рама сопротивлялась'   # строка в одинарных кавычках

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

Ассоциативные массивы (хеши)

Задавая вопрос о том, что такое ассоциативный массив (или хеш) можно получить примерно такие ответы: "Знаешь, что такое массив? Вот хеш, это когда в качестве индекса может использоваться любой объект" или "Массив -- это частный случай хеша". Давайте самостоятельно разберемся, что такое ассоциативный массив. Ассоциативный массив — это неупорядоченная последовательность пар вида ключ-значение. В качестве ключа или значения может выступать любой объект.

Понятие ассоциативного массива было взято из языка Perl. Поэтому и выглядит он в Ruby точно также, как в Perl. Чтобы пояснить, как он выглядит, просто приведу пример хеша:

{ "мама" => "мыла раму", "рама" => "сопротивлялась"}
"npeBeg" => "MegBeg"

В первом примере, фигурными скобками явно указывается, что это хеш. Во втором примере, фигурные скобки обсутствуют, но "стрелка" (или "конструктор пары") указывает, что это все таки хеш.

Диапазоны значений

Для того, чтобы было удобней получать подмассив или подстроку, был введен простенький тип данных — диапазон (класс Range). Диапазон формируется тремя элементами: начало, конец и тип протяженности (символ .. или ...). Начало и конец должны быть одного типа данных (одного класса) и быть перечислимыми (иметь метод .succ). Пример диапазонов:

'a'..'z'
'a'...'z'  # тоже самое, что и 'a'..'y'
1..100
1...100    # тоже самое, что и 1..99

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

Подробнее о числах

Изначально числа представлены тремя типами: два целые типа (классы Fixnum и Bignum) и один дробный (класс Float). Возможно подключение дополнительных типов, но пока ограничимся тремя.

Целые числа

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

Правило: как только число типа Fixnum становится больше (по модулю), то оно преобразовывается к классу Bignum. Если число типа Bignum становится меньше , то оно преобразовывается к типу Fixnum.

При записи целых чисел сначала указывается знак числа (знак + обычно не пишется). Далее идет основание системы счисления, в которой задается число (если оно отлично от десятичной): 0 - для восьмеричной, 0x - для шестнадцатеричной, 0b - для двоичной. Затем идет последовательность цифр, выражающих число в данной системе счисления. При записи чисел можно использовать символ подчеркивания, который игнорируется при обработке. Для того, чтобы закрепить вышесказанное, посмотрим примеры целых чисел:

# тип Fixnum
123_456     # подчеркивание игнорируется	   
-567	     # отрицательное число	   
0xbad       # шестнадцатеричное число	   
0377        # восьмеричное	   
-0b101010   # отрицательное двоичное	   
0b0101_0101 # подчеркивание игнорируется	
  
# тип Bignum
123_456_789_123_456    # подчеркивание игнорируется	   
-123_456_789_123_456   # отрицательное
07777777777777777777   # восьмеричное большое

Как видно из примеров, маленькие целые (Fixnum) и большие целые (Bignum) отличаются только значением.

Дробные числа

Дробные числа задаются только в десятичной системе счисления, при этом для отделения дробной части используется символ . (точка). Для задания дробных чисел может быть применена и экспоненциальная форма записи: два различных представления -0.1234e2 и 1234e-2 задают одно и тоже число 12.34.

# тип Float
-12.34     # отрицательное дробное	   
0.1234е2   # экспоненциальная форма для числа 12.34   
1234е-2    # экспоненциальная форма для числа 12.34

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

Семейный портрет чисел

Здесь планируется картинка с иерархией классов чисел. В том числе и подключаемых. Но у меня пока не получается вставлять картинки. Rubynovich 16:26, 26 мая 2006 (UTC)

Арифметические операции

Арифметические операторы в Ruby точно такие же, как и в математике: сложение (+), вычитание (-), умножение (*), деление (/), получение остатка от деления (%), возведение в степень (**).

6 + 4     #-> 10
6 - 4     #-> 2
6 * 4     #-> 24
6 / 4     #-> 1
6 % 4     #-> 2
6 ** 4    #-> 1296

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

2 + 2 * 2     #-> 6
(2 + 2) * 2   #-> 8
знак операции название
+
сложение
-
вычитание
*
умножение
/
деление
%
остаток от деления
**
возведение в степень

Первое, что бросается в глаза — результат арифметической операции двух целых чисел всегда будет целым. Особенно это видно во время деления двух чисел. Пример:

1/3  # 0
2/3  # 0
3/3  # 1

Для того, чтобы запомнить эту "странность" в поведении целых чисел, был даже придуман небольшой стишок:

Одна вторая в Ruby нуль,
А три вторые -- единица.
Запомнить надо эту соль,
Чтоб результату не дивиться.

Правило: Если все аргументы арифметического выражения целые числа, то результат будет целым, если хотя бы одно дробное, то результат будет дробным. Посмотрим, как будут выглядеть результаты в случае, когда одно из чисел будет дробным.

6.0 + 4     #-> 10.0
6 - 4.0     #-> 2.0
6.0 * 4.0   #-> 24.0
6.0 / 4     #-> 1.5 (одно из чисел дробное, а значит результат -- дробный)
6.0 % 4     #-> 2.0
6 ** 4.0    #-> 1296.0

Кстати, лучше проверить эти сведения самостоятельно. Для этого даже не обязательно устанавливать интерпретатор Ruby. Достаточно лишь зайти на сайт try ruby!.

Поразрядная арифметика

знак операции название
&
побитовое "и"
|
побитовое "или"
^
побитовое "исключающее или"
<<
побитовый сдвиг право
>>
побитовый сдвиг влево
~
побитовая инверсия

Операции побитовой арифметики заимствованы из языка Си. На этот раз без всяких экзотических особенностей. Посмотрим работу этих операций на примере:

6 & 4     #-> 4
6 | 4     #-> 6
6 ^ 4     #-> 2
6 << 4    #-> 96
6 >> 4    #-> 0 (слишком на много сдвинули)
~4        #-> -5 (операция только над одним аргументом)

Здесь вроде как все понятно и без дополнительных пояснений. А если не понятно, то справочник по языку Си вам поможет во всем разобраться.

Методы явного преобразования типов

Метод Операция
to_f преобразовать в дробное
to_i преобразовать в целое
to_s преобразовать в строку
to_a преобразовать в массив

Методы преобразования типов в Ruby традиционно начинаются с приставки to_. Последующая буква -- это сокращение от названия класса, в который происходит преобразование (f - Float - дробное, i - Integer - целое, s - String - строка, a - Array - массив).

Хитрости

Задача: дано целое число, необходимо преобразовать его в двоичную систему счисления.

ucxogHoe_4ucJIo = 1234
puts sprintf("%b",ucxogHoe_4ucJIo) # метод sprintf заимствован из Си
puts ucxogHoe_4ucJIo.to_s(2)       # современный метод

Задача: дано целое число, необходимо поменять порядок цифр в нем на обратный.

ucxogHoe_4ucJIo = 1234
puts ucxogHoe_4ucJIo.to_s.reverse  # метод reverse - переворачивает строку

Задача: дано целое число, необходимо получить значение N-го двоичного разряда.

ucxogHoe_4ucJIo, N = 1234, 5
puts ucxogHoe_4ucJIo[ N ]

Задача: даны два целых числа, необходимо поменять из значения, без использования третей переменной.

ucxogHoe_nepBoe, ucxogHoe_BTopoe = 134, 234
ucxogHoe_nepBoe, ucxogHoe_BTopoe = ucxogHoe_BTopoe, ucxogHoe_nepBoe
puts ucxogHoe_nepBoe, ucxogHoe_BTopoe

Задача: дано дробное число, необходимо округлить его до двух десятичных разрядов.

gpo6Hoe_4ucJIo = 3.1415926535
puts ( gpo6Hoe_4ucJIo * 100 ).to_i.to_f / 100
puts sprintf( "%.2f", gpo6Hoe_4ucJIo ).to_f    # полуСишный способ =)

Задачи

Подробнее о массивах

Способы создания массива

Диапазоны

У диапахонов есть очень полезное свойство: наличие метода to_a. Это значит, что любой диапазон значений можно с легкостью превратить в массив. Этот массив будет содержать все элементы, которые входят в данный диапазон.

(1..10).to_a      #->  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
('a'..'d').to_a   #->  ['a', 'b', 'c', 'd']

Раз уж речь зашла о диапазонах, то давайте посмотрим, как они позволяют получать подмассивы. И насколько изящно у них это получается. Рассмотрим массив:

[ 'a', 'b', 'c', 'd', 'e']

Всем нам известно, как нумеруются элементы массива: нумерация начинается с нуля и далее по возрастающей.

[ 'a', 'b', 'c', 'd', 'e' ]

Такая нумерация называется в Ruby "положительной индексацией". Хм, — скажете вы, — а есть еще и "отрицательная"? Да, есть!

[ 'a', 'b', 'c', 'd', 'e' ]

Кстати, плюсы поставлены для красоты. И без них все будет работать. Но вернемся к отрицательной индексации. Какой ее смысл? Для того, чтобы его пояснить, давайте решим задачку: дан массив, необходимо получить предпоследний элемент.

maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ maccuB.size - 2 ]

В данном случае, мы использовали метод .size, который возвращает размер массива. Разработчики языка Ruby заметили, что вызов maccuB.size приходится писать с завидной регулярностью. И решили от него избавиться. И получилось вот что:

maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ -2 ]     #-> 'd'

Индекс -2 имеет смысл: "предпоследний элемент массива". Вот так и появилась отрицательная индексация. Теперь давайте разберемся с диапазонами. Оказывается в них тоже можно использовать отрицательную индексацию. На этот раз решим другую задачку: необходимо получить все элементы массива, кроме первого и последнего. Вот как она решается:

maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ 1..-2 ]  #-> ['b', 'c', 'd']

или

maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ 1...-1 ]  #-> ['b', 'c', 'd']

Второй вариант с тремя точками, что автоматически приближает правую границу диапазона на одну позицию влево.

Методы работы с массивами

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

Поиск максимального/минимального элемента

Вспомните сколько усилий вам приходилось прилагать, чтобы найти максимальный элемент? А сколько раз вы повторяли этот кусок кода в своих программах? Ну а в Ruby поиск максимального элемента осуществляется при помощи метода .max, а в более сложных случаях при помощи метода .max_by (начиная с версии 1.9). Вот как это выглядит:

['y','nona','6bIJIa','co6aka'].max                          #-> 'y'       максимальный по значению
['y','nona','6bIJIa','co6aka'].max_by{ |elem| elem.size }   #-> '6bIJIa'  максимальный по размеру строки

Методы .min и .min_by работают аналогично:

['y','nona','6bIJIa','co6aka'].min                         #-> '6bIJIa'   минимальный по значению
['y','nona','6bIJIa','co6aka'].min_by{ |elem| elem.size }  #-> 'y'        максимальный по размеру строки

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

Сортировка по возрастанию

Не буду "травить душу" долгими байками. Для того, чтобы отсортировать массив, необходимо вызвать метод .sort или .sort_by (начиная с версии 1.8).

['y','nona','6bIJIa','co6aka'].sort                         #-> ["6bIJIa", "co6aka", "nona", "y"] сортировка по значению
['y','nona','6bIJIa','co6aka'].sort_by{ |elem| elem.size }  #-> ["y", "nona", "6bIJIa", "co6aka"] сортировка по размеру строки

Остается только добавить, что массивы сортируются по возрастанию. А вот если вам необходимо осуществить сортировку по убыванию, то придется писать собственный метод сортировки "пузырьком". Шутка! Существует несколько путей решения этой задачи. На данный момент мы будем использовать метод .reverse, речь о котором пойдет ниже.

Обращение (перевертывание) массива

Определение: Обращение массива &mdash это процесс изменения порядка элементов на обратный, т.е. первый элемент становится последним, второй элемент предпоследним и т.д.

Для обращения массива существует метод .reverse. Применим его к предыдущим примерам, чтобы получить сортировку по убыванию:

['y','nona','6bIJIa','co6aka'].sort.reverse                         #-> ["y", "nona", "co6aka", "6bIJIa"]
['y','nona','6bIJIa','co6aka'].sort_by{ |elem| elem.size }.reverse  #-> ["co6aka", "6bIJIa", "nona", "y"]

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

Сложение/вычитание массивов

Объединение и пересечение массивов (как множеств)

Итераторы

Хитрости

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

cumBoJIbI = ['a'..'z','A'..'Z','0'..'9'].map{ |range| range.to_a }.flatten
puts (0...8).map{ cumBoJIbI[ rand( cumBoJIbI.size ) ] }.join

Задачи

Одномерные

Двумерные

Подробнее об ассоциативных массивах

Способы создания ассоциативного массива

Методы работы с ассоциативными массивами

Хитрости

Задачи

Подробнее о строках

Способы создания строки

Методы работы со строками

«Правила» поиска, сравнения, разбиения и замены

Хитрости

Задачи

Справочник. Простейшие типы данных

Числа

Маленькие целые

Большие целые

Дробные

Массивы

Ассоциативные массивы

Строки

Способы расширения библиотеки методов

Как добавить метод к массиву/строке/венику?

Как написать свой итератор?

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

Наследовать или перемешать?

Как сделать свою библиотеку методов?

Матрицы и вектора

Способы создания

Методы работы

Хитрости

Задачи

Файлы

Способы создания файла

Запись, чтение

Пишем объекты в файл

Marshal

YAML

Хитрости

Задачи

Сети

Гнезда, которые свили не птицы

Приемо-передача файлов

Скачиваем HTML страничку

Вам письмо или You have got mail

Запускаем свой Web-сервер

Справочник. Второе приближение

Матрицы

Вектора

Файлы

IO

File

Сети

Sockets

FTP

HTTP

Программистские байки

О том, как начальник без отдела работу выполнял

О том, как программа склероз лечит

О том, как программист Excel укрощал

О том, как программа задачки придумывала

О том, как файлы с RapidShare качать

О том, как музыку на FTP искать

О том, как киберсквотеров разорили

Философская страничка

Почему скорость написания программы важнее скорости ее выполнения?

Эволюция программ: от столбиков к строчкам

Куда подевались циклы?

Почему исчезают переменные?

Как японская письменность повлияла на язык Ruby?

Нужны ли нам условные операторы if и case?

Почему Java/C# популярней Ruby?

RoR != Ruby

См.также