Скриптовый язык Ruby. Легкий путь в мир программирования. Часть 3

Переменные и константы

Переменные

Когда транслятор резервирует область памяти для хранения данных, ее нужно в тексте программы как-то поименовать. Потом в процессе работы программы значение и характер этих данных могут меняться. Это и называется переменной.

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

Вот, к примеру:

a = 5

a = "Теперь это текст"

a = ["А" "теперь", "это,", "вообще, массив"]

В Ruby имя переменной (оно же идентификатор) должно начинается со строчной латинской буквы. Вообще идентификатор переменной может состоять из латинских букв, цифр и знака подчеркивания «_».

Переменные в Ruby делятся на локальные и глобальные. Локальные переменные действуют в пределах основного текста программы или же отдельной подпрограммы, глобальные же – в пределах всей программы, включая все подпрограммы. Глобальные переменные обозначаются символом «$» перед идентификатором.

$a = 22

Также существуют переменные экземпляра (instance) и переменные класса. Они будут подробно рассмотрены ниже.
Назначать значения переменным можно сразу «гуртом».

a, b, c, d = 5333, 0xFE, ?б, "Текст"

e, f = a+b, c

И даже так:

a = b = c = 22

Все три переменные, как нетрудно догадаться, примут значение 22.

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

a = 445

a = a + 23

Более того, эти самые операции можно записывать в такой вот сокращенной форме:

a+=23

Эта короткая форма подходит для многих арифметических (+, -, *, /, %, **) и логических (&, |, ^, <<, >>, &&) операторов.

В Ruby имеется довольно большое количество встроенных или предопределенных переменных, большей частью унаследованных из Perl. Обращаясь к ним, можно получать некоторые системные параметры (или изменять их). Например, переменная $_ содержит последнюю введенную строку, а $/ - разделитель для вводимых строк.

Также предусмотрено несколько так называемых псевдопеременных. «Псевдо» — потому что хотя они и воспринимаются транслятором как
переменные, изменить их значение не представляется возможным.

К псевдопеременным относятся: false, nil, self, true, __FILE__, __LINE__.

Константы

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

MY_CONST = 3,74

К попыткам переопределить константу Ruby относится довольно лояльно. Будет выведено сообщение вроде:

test.rb:2: warning: already initialized constant MY_CONST

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

Есть и встроенные (они же глобальные) константы. При помощи их осуществляется, например, такая важная вещь, как ввод данных через консоль (константы ARGV и ARGF) Также можно узнать, к примеру, версию транслятора (RUBY_VERSION) и т.д.

Массивы

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

Объявить новый массив можно так:

mass = Array.new # пустой массив

mass2 = [] # тоже пустой массив

massv = Array.new (10) # массив в 10 пустых элементов

В последнем случае все 10 элементов первоначально будут иметь значение nil.
Можно заранее наполнить массив данными.

data1 = [ 233, 6449, "оранжевый", 0xAF, a+=40, "синий",

["это вложенный массив", 2], 45]

Как видим, понятие «данные разных классов» включает не только выражения, но и другие массивы. Таким образом можно организовать многомерные массивы.
Обращение к отдельному элементу происходит с помощью его порядкового номера – индекса. Нумерация элементов в массиве начинается с 0. Индекс может быть и отрицательным. В этом случае Ruby считает, что нумерация начинается с конца.

Если массив состоит только из строковых данных, то его можно объявить и вот так:

arr1 = %w(двадцать тридцать сорок)

arr2 = %w(двадцать один\ двадцать два\ двадцать три)

Как видно из примера, разделитель «\» применяется в том случае, если строковые данные состоят из нескольких слов.

Еще пару слов о многомерных массивах. Степень вложенности их практически не ограничена. А обращение к конкретному элементу происходит вот так:

arr = [23, [[76, 21, 45], 23]] # трехмерный массив

p arr [1][0][2] # обращение к элементу со значением 45

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

Хэши

Хэш – почти тот же массив, но вместо индекса (числовое значение) каждый его элемент имеет ключ (строковое значение). Собственно, хэши и состоят из пар «значение-ключ», поэтому их еще называют ассоциативными массивами. Это делает хэши удобным средством для оформления словарей, таблиц подстановки и прочих данных, требующих структурирования и систематизации.

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

Объявление хэшей немного похоже на объявление массивов.

Новый хэш:

MyHash = Hash.new

Хэш с данными:

phonetab = {"507-74-36" => "Прушинский В.В.",

"139-42-12" => "Комаров А.Т.",

"234-35-27" => "Скакалова А.Я",

"721-61-54" => "Лайко А.Г."}

Вот такая у нас получилась телефонная книга. Попробуем обратиться к одному из элементов:

puts phonetab[”139-42-12”]

Обращение такое же, как к элементу массива, только вместо индекса – текстовый ключ. Результат, выведенный на экран, вполне предсказуем:
Комаров А.Т.

А вот своеобразная база знаний. Название животного и его принадлежность к классу.

zoo = {"дятел" => "птица", "лещ" => "рыба",

"щука" => "рыба", "филин" => "птица",

"удод" => "птица", "окунь" => "рыба"}

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

Побочным эффектом этого приема будет такой момент. Узнать принадлежность животного (получить данные по ключу) проще простого, но чтобы получить, допустим, список животных, относящихся к классу «рыбы», нужно будет прибегнуть к небольшому ухищрению.

Средства ввода-вывода

Вывод данных


С наиболее часто используемой командой вывода вы уже познакомились. Это puts.

puts 35, [2, 4, 14], "Текст", 4 * 6

После выполнения этой команды на экране появится следующая информация:

35

2

4

14

Текст

24

Команда без аргументов

puts

выводит просто пустую строку.

А как быть, если нужно вывести все аргументы в одну строку? Для этого в Ruby предусмотрена команда print.

print 35, [2, 4, 14], "Текст", 4 * 6

Результатом ее работы будет:

352414Текст24

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

print 35, " ", [2, 4, 14], " ", "Текст", " ", 4 * 6

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

p 35, [2, 4, 14], "Текст", 4 * 6

Результатом ее будет:

35

[2, 4, 14]

“\222\245\252\341\342”

24

Конечно, это не идеальный вариант, но простое число от массива, по крайней мере, отличить можно. Символы из второй половины таблицы ASCII (>128) отображаются в виде восьмеричных кодов.

Ввод данных

Для того чтобы программа в процессе работы могла получать пользовательские данные, в Ruby наличествует команда gets.

a = gets

При поступлении данной команды интерпретатор приостанавливает работу скрипта и ждет ввода строки с клавиатуры. По его завершении (нажатие клавиши Enter) означенная строка присваивается переменной (причем код Enter (newline) входит в нее) и выполнение скрипта продолжается. Упомянутый код newline является завершающим (record separator) лишь по умолчанию. Достаточно изменить значение системной переменной $/, чтобы заканчивать ввод строки нажатием любой другой клавиши.

Если код Enter не нужен, можно сразу отсечь его.

a = gets.chomp

Можно присвоить значение сразу нескольким переменным.

a = b = gets

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

print "Введите требуемый вес: "; a = gets

У метода gets существует синоним: readline.

a = readline

Этот метод немного отличается от gets поведением при работе с файлами, а в остальном они полностью идентичны.

Последнее значение, введенное при помощи метода gets или readline, сохраняется во встроенной переменной $_, откуда его можно, при
надобности, извлечь.

Кроме ввода с клавиатуры в процессе работы программы, данные пользователя можно «скармливать» ей непосредственно перед запуском.

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

Давайте создадим демонстрационный скрипт square.rb со следующим текстом:

p ARGV

puts "Площадь: #{ARGV[0].to_f * ARGV[1].to_f}"

Скрипт содержит команды полного дампа содержимого массива ARGV и вычисления площади прямоугольника с выводом результата.

Запустим его:

ruby t5.rb 56 111

Получим:

["56", "111"]

Площадь: 6216.0

Как видим, аргументы следуют сразу за именем скрипта. Разделителем служит пробел. В порядке следования они и попадают в служебный массив ARGV. Все элементы этого массива относятся к классу String. Поэтому, если планируются действия, характерные для других классов, например вычисления, то потребуется их соответствующая конвертация.

Юзич yuzich17@mail.ru

© Компьютерная газета :: главная страница