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

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

Жанры

Программирование на языке 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
ведет себя аналогично, только возвращает массив, содержащий РМ, и сдвинутый влево код завершения.

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

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

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

На цепи

Уваров
1. На цепи
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
На цепи

Господин Хладов

Шелег Дмитрий Витальевич
4. Кровь и лёд
Фантастика:
аниме
5.00
рейтинг книги
Господин Хладов

Двойник Короля 10

Скабер Артемий
10. Двойник Короля
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Двойник Короля 10

Я до сих пор не князь. Книга XVI

Дрейк Сириус
16. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я до сих пор не князь. Книга XVI

Великий князь

Кулаков Алексей Иванович
2. Рюрикова кровь
Фантастика:
альтернативная история
8.47
рейтинг книги
Великий князь

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Изгой Проклятого Клана

Пламенев Владимир
1. Изгой
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Изгой Проклятого Клана

Наследник

Назимов Константин Геннадьевич
3. Травник
Фантастика:
фэнтези
6.80
рейтинг книги
Наследник

Хозяин Стужи

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

Убийца

Бубела Олег Николаевич
3. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Убийца

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3

Леди Малиновой пустоши

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Леди Малиновой пустоши

Позывной "Князь" 2

Котляров Лев
2. Князь Эгерман
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Позывной Князь 2