Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на языке Ruby.docx
Скачиваний:
19
Добавлен:
06.09.2019
Размер:
1.74 Mб
Скачать

14.9.2. Подача входных данных Ruby по конвейеру

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

В листинге 14.6 представлен bash-сценарий, который вызывает Ruby (посредством вложенного документа) для вычисления интервала в секундах между двумя моментами времени. Ruby-программа печатает на стандартный вывод одно значение, которое перехватывается вызывающим сценарием.

Листинг 14.6. Bash-сценарий, вызывающий Ruby

#!/usr/bin/bash

# Для вычисления разницы в секундах между двумя моментами временами

# bash вызывает Ruby...

export time1="2007-04-02 15:56:12"

export time2="2007-12-08 12:03:19"

cat <<EOF | ruby | read elapsed

require "parsedate"

time1 = ENV["time1"]

time2 = ENV["time2"]

args1 = ParseDate.parsedate(time1)

args2 = ParseDate.parsedate(time2)

args1 = args1[0..5]

args2 = args2[0..5]

t1 = Time.local(*args1)

t2 = Time.local(*args2)

diff = t2 — t1

puts diff

EOF

echo "Прошло секунд = " $elapsed

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

time1="$time1" # Включить переменные оболочки непосредственно

time2="$time2" # в строку...

Но возникающие при этом проблемы очевидны. Очень трудно понять, имеется ли в виду переменная bash или глобальная переменная Ruby. Возможна также путаница при экранировании и расстановке кавычек.

Флаг -e позволяет создавать однострочные Ruby-сценарии. Вот пример обращения строки:

#!/usr/bin/bash

string="Francis Bacon"

ruby -e "puts '$string'.reverse" | read reversed

# $reversed теперь равно "nocaB sicnarF"

Знатоки UNIX заметят, что awk использовался подобным образом с незапамятных времен.

14.9.3. Получение и установка кодов завершения

Метод exit возбуждает исключение SystemExit и в конечном счете возвращает указанный код завершения операционной системе (или тому, кто его вызвал). Этот метод определен в модулеKernel. Метод exit! отличается от него в двух отношениях: он не выполняет зарегистрированные обработчики завершения и по умолчанию возвращает -1.

# ...

if (all_OK)

 exit # Нормально (0).

else

 exit! # В спешке (-1).

end

Когда операционная система печатает возвращенный Ruby код (например, выполнив команду echo $?), мы видим то же самое число, что было указано в программе. Если завершается дочерний процесс, то код его завершения, полученный с помощью метода wait2 (или waitpid2), будет сдвинут влево на восемь битов. Это причуда стандарта POSIX, которую Ruby унаследовал.

child = fork { sleep 1; exit 3 }

pid, code = Process.wait2 # [12554,768]

status = code << 8 #3

14.9.4. Работает ли Ruby в интерактивном режиме?

Чтобы узнать, работает ли программа в интерактивном режиме, нужно проверить стандартный ввод. Метод isatty? возвращает true, если устройство интерактивное, а не диск или сокет. (Для Windows этот метод не реализован.)

if STDIN.isatty?

 puts "Привет! Я вижу, вы печатаете"

 puts "на клавиатуре."

else

 puts "Входные данные поступают не с клавиатуры."

end