Как вы можете взаимодействовать с Perl-программами из Ruby? - PullRequest
6 голосов
/ 22 января 2010

Насколько я понимаю, между Ruby и Perl нет "моста", который позволял бы вам вызывать функции Perl непосредственно из Ruby. Я также понимаю, что для вызова Perl-программы из Ruby вы просто помещаете ее в кавычки (т. Е. result = `./helloWorld.pl`). Однако это не позволяет взаимодействовать с программой Perl (то есть вы не можете взаимодействовать с подсказками или вводить данные). Мои квесты следующие:

  1. Есть ли способ предоставить входные данные для программ Perl из Ruby (кроме аргументов)?

  2. Я ошибаюсь, что между Ruby и Perl нет моста? Взаимодействие с программным stdin кажется неправильным при навигации по подсказкам, и программы, с которыми я имею дело, хорошо разработаны и имеют библиотеки с соответствующими функциями Perl.

Ответы [ 8 ]

5 голосов
/ 26 января 2010

Использовать exec Руби ()

rubypl.rb

#!/usr/bin/ruby -w

script = 'perlscript.pl'
exec("/usr/bin/perl #{script}")

perlscript.pl

#!/usr/bin/perl -w
use strict;
print "Please enter your name: ";
my $name = <STDIN>;
chop($name);
if ($name eq "")
{
    print "You did not enter a name!\n";
    exit(1);
} else {
    print "Hello there, " . $name . "\n";
    exit(0);
}
5 голосов
/ 22 января 2010

Есть модуль Inline :: Ruby , хотя у меня нет прямого опыта с ним, которым я могу поделиться.

РЕДАКТИРОВАТЬ : я попробовал это вчера вечером - вот обзор: Inline::Ruby последний раз обновлялся в 2002 году, когда v5.6 был последним стабильным выпуском. Документы говорят, что это было проверено только на Linux; Я пытался использовать его с v5.10.1 на Cygwin. Получил его для сборки после некоторого взлома кода XS / C, поставляемого с модулем. Пройдены некоторые юнит-тесты, но не прошли другие Казалось, что импортировать Ruby class в пространство имен Perl нормально, но импорт автономных функций оказался менее успешным. Резюме: если вам нужен быстрый и грязный мост для Perl и Ruby, Inline::Ruby, вероятно, разочарует вас. Если у вас хватит терпения выяснить, как создать модуль в вашей системе, и поменять код Ruby для работы с этим модулем, вы можете найти его полезным.

3 голосов
/ 22 января 2010

perldoc perlipc состояния:

DESCRIPTION
       The basic IPC facilities of Perl are built out of the good old Unix
       signals, named pipes, pipe opens, the Berkeley socket routines, and
       SysV IPC calls.  Each is used in slightly different situations.

Ruby способен работать с каждым из них.

3 голосов
/ 22 января 2010

Вот как ruby ​​может использовать скрипт на python, взаимодействуя со сценарием stdin и stdout.

foo.py читает два целых числа (каждое в своей строке) из стандартного ввода, добавляет их и записывает результат в стандартный вывод. Я не знаю Perl, так что будь мил со мной:

#!/usr/bin/perl

$a = <STDIN>;
$b = <STDIN>;
$c = int($a) + int($b);
print $c;

foo.rb выполняет foo.py, давая ему два числа для добавления, возвращает результат и печатает его:

#!/usr/bin/ruby1.8

a = 1
b = 2
c = IO.popen('./foo.py', 'w+') do |pipe|
  pipe.puts(a)
  pipe.puts(b)
  pipe.close_write
  pipe.read
end
raise "foo.py failed" unless $? != 0
print "#{a} + #{b} = #{c}"    # => 1 + 2 = 3
2 голосов
/ 22 января 2010

То, что вы хотите, на самом деле не существует, насколько мне известно.

На общем уровне наиболее близким к тому, что вам нужно, является XDebug . Он превращает процесс в маленький сервер, который будет принимать команды отладки. Это обычно используется для отладки и профилирования, а не как межпроцессное взаимодействие, но это возможно. Я считаю, что Perl ActiveState может быть запущен как сервер XDebug.

В противном случае вам необходимо явно запрограммировать какой-то побочный канал, который ваша Perl-программа слушает для команд (что делает XDebug). Это может быть так же просто, как открыть сокет, который читает строку, проверяет ее, кодирует результат как YAML (или что-то еще) и записывает обратно. REPL, но не на терминале, а на сокете.

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

Извините, у меня нет ничего более конкретного. Это сделало бы отличный модуль CPAN.

2 голосов
/ 22 января 2010

Попробуйте Open4 . Он не предназначен специально для взаимодействия с Perl, но с любой программой, которая требует ввода и вывода. Я все еще учусь его использовать, но я чувствую, что он может удовлетворить ваши потребности.

2 голосов
/ 22 января 2010

Perl и Ruby имеют разные "клеи". Программы на Perl, использующие модуль Expect, могут сделать гораздо больше, чем просто «ждать вывода». Скорее всего, вы могли бы общаться с известным протоколом, таким как HTTP ... демон Ruby мог установить слушателя, и Perl мог связаться с ним, или наоборот.

Но нет, вы не можете просто "встроить" рубиновый код в Perl или наоборот. Вы должны запустить отдельные процессы и как-то общаться.

0 голосов
/ 22 января 2010

Вы упомянули в одном из ваших комментариев, что хотите запустить Perl-код внутри Ruby. Это не будет работать, если вы не можете заставить интерпретатор Ruby понимать синтаксис Perl. Могу ли я получить BNF / yacc / RE для языка Perl? поможет вам понять проблемы, с которыми вы столкнетесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...