Вставить Python CLI в процесс Ruby? - PullRequest
5 голосов
/ 09 августа 2011

В рамках более крупного проекта я пытаюсь «встроить» интерактивный интерпретатор Python в процесс Ruby.Я хотел бы иметь возможность сделать что-то вроде следующего:

$ irb
irb(main):001:0> pipe = IO.popen("python", "w+")
=> #<IO:0x7f3dba4977e0>
irb(main):002:0> pipe.puts "print 'hello'"
=> nil
irb(main):003:0> pipe.gets
=> 'hello\n'

К сожалению, gets, похоже, зависает, а не возвращает какой-либо вывод из процесса Python.Я пробовал варианты этой процедуры с open3, используя режим r+ вместо w+ и несколько других незначительных опций (среди них python -u), но безуспешно.способ наладить интерактивное взаимодействие с оболочкой Python из Ruby - по сути, «обернуть» Python CLI?Я использую Ruby 1.8.7 (2010-06-23 patchlevel 299) и Python 2.6.6 на компьютере x86_64, хотя, надеюсь, решения будут переносимыми (ish) для всех версий Python.

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Вот альтернативный подход, использующий псевдо-терминальную библиотеку Ruby.Я протестировал это с ruby ​​1.9 на Linux и MacOS X, он, вероятно, не будет работать на Windows:

1 голос
/ 09 августа 2011

popen не похож на терминал для Python, поэтому вы не работаете в интерактивном режиме.Вы можете принудительно запустить python в интерактивном режиме с помощью -i:

IO.popen("python -i", "r+") do |py|
  while cmd = gets
    py.puts cmd
    puts py.gets
  end
end

Возможно, вам придется проделать определенную работу, чтобы удалить приглашение >>> и т. Д.

РЕДАКТИРОВАТЬ : вот многострочная дружественная версия (я сохраняю код понятен и ответил на оригинальный вопрос):

IO.popen("python -i", "r+") do |py|
  loop do
    fds = IO.select [py, STDIN]
    fds.each do |(fd)|
      case fd
      when nil;    next
      when STDIN;  py.puts gets
      else;        puts py.gets
      end
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...