Программирование на языке Ruby.

10.1.13. Каналы.

Ruby поддерживает разные способы читать из канала и писать в него. Метод класса IO.popen открывает канал и связывает с возвращенным объектом стандартные ввод и вывод процесса. Часто с разными концами канала работают разные потоки, но в примере ниже запись и чтение осуществляет один и тот же поток:

Check = IO.popen("spell","r+").

Check.puts("'T was brillig, and the slithy toves").

Check.puts("Did gyre and gimble in the wabe.").

Check.close_write.

List = check.readlines.

List.collect! { |x| x.chomp }.

# list равно %w[brillig gimble gyre slithy toves wabe].

Отметим, что вызов close_write обязателен, иначе мы никогда не достигнем конца файла при чтении из канала. Существует также блочная форма:

File.popen("/usr/games/fortune") do |pipe|

Quote = pipe.gets.

Puts quote.

# На чистом диске можно искать бесконечно. - Том Стил.

End.

Если задана строка "-", то запускается новый экземпляр Ruby. Если при этом задан еще и блок, то он работает в двух разных процессах, как в результате разветвления (fork); блоку в процессе-потомке передается nil, а в процессе-родителе — объект IO, с которым связан стандартный ввод или стандартный вывод.

IO.popen("-").

Do |mypipe|

 if mypipe.

  puts "Я родитель: pid = #{Process.pid}".

  listen = mypipe.gets.

  puts listen.

 else.

  puts "Я потомок: pid = #{Process.pid}".

 end.

End.

# Печатается:

# Я родитель: pid = 10580.

# Я потомок: pid = 10582.

Метод pipe возвращает также два конца канала, связанных между собой. В следующем примере мы создаем два потока, один из которых передает сообщение другому (то самое сообщение, которое Сэмюэль Морзе впервые послал по телеграфу). Если вы не знаете, что такое потоки, обратитесь к главе 3.

Pipe = IO.pipe.

Reader = pipe[0].

Writer = pipe[1].

Str = nil.

Thread1 = Thread.new(reader,writer) do |reader,writer|

 # writer.close_write.

 str = reader.gets.

 reader.close.

End.

Thread2 = Thread.new(reader,writer) do |reader,writer|

 # reader.close_read.

 writer.puts("What hath God wrought?").

 writer.close.

End.

Thread1.join.

Thread2.join.

Puts str # What hath God wrought?