你如何从Ruby与Perl程序进行交互?

6
据我所知,Ruby和Perl之间没有“桥梁”可以让您直接从Ruby调用Perl函数。据我了解,要从Ruby调用Perl程序,只需将其放在反引号中(即result = `./helloWorld.pl`)。但是,这不允许与Perl程序交互(例如,您无法与提示交互或提供输入)。我的问题如下:
  1. 除了参数之外,是否有其他方法可以从Ruby向Perl程序提供输入?

  2. 我是否错误地认为Ruby和Perl之间没有桥梁?当导航提示时,与程序的stdin交互似乎是错误的方式,而我处理的程序设计良好,并且具有适当的Perl函数库。


1
从你对答案的评论来看,似乎你正在寻找能够调用运行中的 Perl 程序内部方法以直接与其交互的东西? - Schwern
是的,我想要能够执行类似perlProgram.execMethod('myPerlPethod')这样的操作,并且能够桥接间隔(哈希、数组、字符串、数字等)。 - Mike
8个回答

5
使用Ruby的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

有一个Inline::Ruby模块,但我没有可以分享的直接经验。

编辑:昨晚我尝试过了--这是我的评论:Inline::Ruby在2002年最新的稳定版本v5.6发布时进行了更新。文档称它只在Linux上进行了测试;我正在尝试在Cygwin上使用v5.10.1。通过对模块附带的XS/C代码进行一些修改,编译成功了。通过了一些单元测试,但失败了一些。似乎将Ruby class导入Perl的命名空间可以,但导入独立函数的效果较差。总结:如果您需要Perl和Ruby之间的快速而脏的桥梁,Inline::Ruby可能会让您失望。如果您有耐心找出如何在您的系统上构建该模块,并调整Ruby代码以使其与该模块一起工作,那么您可能会发现它有用。


1
这与我想要做的相反 - 我想在 Ruby 中运行 Perl 代码。 - Mike
1
Mike:Inline:: 模块通常允许回调到 Perl 代码。因此,您可以从小的 Perl 程序运行您的 Ruby 程序。 - Alexandr Ciornii

3
这里是如何使用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

3

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能够操作它们中的每一个。

2
Perl和Ruby都有各种不同的“粘合剂”。使用Expect模块的Perl程序不仅可以“等待输出”,而且可以做很多其他事情。更有可能的是,您可以与像HTTP这样的知名协议进行通信... Ruby守护程序可以设置侦听器,Perl可以联系它,反之亦然。
但是,不能将Ruby代码“嵌入”到Perl中,反之亦然。您必须运行单独的进程并以某种方式进行通信。

我理解需要有粘合剂 - 但是否有软件可以处理这个问题?只要它写得好,我不介意使用进程间中介。 (如果可能的话,我想避免编写一个。) - Mike
2
Inline::Ruby 允许在 Perl 程序中运行 Ruby 代码。它还允许调用 Perl 子程序,因此可以将 Ruby 用作主要语言。 - Alexandr Ciornii
你可以将Perl嵌入到Ruby以及任何其他的C程序中。虽然你可能不想这样做,但Perl被设计成允许这样做。反过来,Perl也有内联模块。 - brian d foy

2
尝试使用Open4。它不是专门为与perl交互设计的,而是适用于任何需要输入和输出的程序。我仍在学习如何使用它,但我觉得它可能适合你的需求。

嗯,这回答了我的第一个问题,但是通过stdin/stdout进行交互仍然让我非常紧张。 - Mike

2
据我所知,你想要的东西实际上并不存在。
通常情况下,最接近你想要的东西是XDebug。它将进程转变为一个小型服务器,可以接受调试命令。这通常用于调试和性能分析,而不是作为进程间通信,但这也是一种可能性。我相信ActiveState的Perl可以作为XDebug服务器运行。
否则,你需要显式地编写一些侧信道代码,在其中设置你的Perl程序监听命令(这就是XDebug所做的)。它可以简单地打开一个套接字,读取字符串,对其进行评估,将结果编码为YAML(或其他格式)并将其写回。类似REPL,但不是在终端上,而是在套接字上。
显然,这会有安全方面的问题,这将留给读者自行解决。同时,你还不希望监听套接字中断程序,因此你现在需要使用事件驱动或线程来完成操作。
非常抱歉,我没有更具体的建议。这会成为一个很好的CPAN模块。

0

1
你不需要Ruby解释器来理解Perl。你只需要将Perl嵌入到Ruby的C扩展中即可。 :) - brian d foy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接