Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

Таким образом, можно добиться более-менее системно-независимого поведения

system
. Но если вы хотите запомнить выведенную программой информацию (например, в переменной), то
system
— не лучший способ (см. следующий раздел).

Упомяну еще метод

exec
. Он ведет себя аналогично
system
с тем отличием, что новый процесс замещает текущий. Поэтому код, следующий за
exec
, исполняться не будет.

puts "Содержимое каталога:"

exec("ls", "-l")

puts "Эта строка никогда не исполняется!"

14.1.2. Перехват вывода программы

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

listing = `ls -l` # Одна строка будет содержать несколько строчек (lines).

now = `date` # "Mon Mar 12 16:50:11 CST 2001"

Обобщенный ограничитель

%x
вызывает оператор обратных кавычек (который в действительности является методом модуля Kernel). Работает он точно так же:

listing = %x(ls -l)

now = %x(date)

Применение

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

Поскольку обратные кавычки — это на самом деле метод (в некотором смысле), то его можно переопределить. Изменим его так, чтобы он возвращал не одну строку, а массив строк. Конечно, при этом мы создадим синоним старого метода, чтобы его можно было вызвать.

alias old_execute `

def `(cmd)

 out = old_execute(cmd) # Вызвать исходный метод обратной кавычки.

 out.split("\n") # Вернуть массив строк!

end

entries = `ls -l /tmp`

num = entries.size # 95

first3lines = %x(ls -l | head -n 3)

how_many = first3lines.size # 3

Как видите, при таком определении изменяется также поведение ограничителя

%x
.

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

alias old_execute `

def `(cmd)

 old_execute(cmd + " 2>&1")

end

entries = `ls -l /tmp/foobar`

# "/tmp/foobar: No such file or directory\n"

Есть, конечно, и много других способов изменить стандартное поведение обратных кавычек.

14.1.3. Манипулирование процессами

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

fork
, название которого в соответствии с традицией UNIX подразумевает разветвление пути исполнения, напоминая развилку на дороге. (Отметим, что в базовом дистрибутиве Ruby метод
fork
на платформе Windows не поддерживается.)

Метод

fork
, находящийся в модуле
Kernel
(а также в модуле
Process
), не следует путать с одноименным методом экземпляра в классе
Thread
.

Существуют два способа вызвать метод

fork
. Первый похож на то, как это обычно делается в UNIX, — вызвать и проверить возвращенное значение. Если оно равно
nil
, мы находимся в дочернем процессе, в противном случае — в родительском. Родительскому процессу возвращается идентификатор дочернего процесса (pid).

pid = fork

if (pid == nil)

 puts "Ага, я, должно быть, потомок."

 puts "Так и буду себя вести."

else

 puts "Я родитель."

 puts "Пора отказаться от детских штучек."

end

В этом не слишком реалистичном примере выводимые строки могут чередоваться, а может случиться и так, что строки, выведенные родителем, появятся раньше. Но сейчас это несущественно.

Следует также отметить, что процесс-потомок может пережить своего родителя. Для потоков в Ruby это не так, но системные процессы — совсем другое дело.

Во втором варианте вызова метод

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

fork do

 puts "Ага, я, должно быть, потомок."

 puts "Так и буду себя вести."

end

puts "Я родитель."

puts "Пора отказаться от детских штучек."

Конечно, pid по-прежнему возвращается, мы просто не показали его.

Чтобы дождаться завершения процесса, мы можем вызвать метод

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

Поделиться:
Популярные книги

Газлайтер. Том 20

Володин Григорий Григорьевич
20. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 20

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Рассвет русского царства

Грехов Тимофей
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Рассвет русского царства

Надуй щеки!

Вишневский Сергей Викторович
1. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки!

Дважды одаренный. Том IV

Тарс Элиан
4. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
7.00
рейтинг книги
Дважды одаренный. Том IV

Боярич Морозов

Шелег Дмитрий Витальевич
3. Наследник старого рода
Фантастика:
героическая фантастика
боевая фантастика
альтернативная история
7.12
рейтинг книги
Боярич Морозов

Старая школа рул

Ромов Дмитрий
1. Второгодка
Фантастика:
альтернативная история
6.00
рейтинг книги
Старая школа рул

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Снайпер

Поселягин Владимир Геннадьевич
3. Жнец
Фантастика:
боевая фантастика
попаданцы
5.60
рейтинг книги
Снайпер

Битва за Изнанку

Билик Дмитрий Александрович
7. Бедовый
Фантастика:
городское фэнтези
мистика
5.00
рейтинг книги
Битва за Изнанку

Вперед в прошлое 8

Ратманов Денис
8. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 8

Хозяин Стужи 4

Петров Максим Николаевич
4. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Хозяин Стужи 4

Вперед в прошлое 4

Ратманов Денис
4. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое 4

Хозяин оков III

Матисов Павел
3. Хозяин Оков
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Хозяин оков III