不,这行不通。至少不是你想象的那样。
Jython 和 JRuby 之间的互操作性与 CPython 和 YARV 之间的互操作性工作方式相同:它们都运行在同一个平台上,因此它们可以使用该平台相互通信。
对于 CPython 和 YARV,该平台是 C/POSIX,因此它们可以使用 C 结构、ints、char*s 和 C 函数调用相互通信。对于 Jython 和 JRuby,该平台就是 JVM,因此它们可以使用 JVM 对象、JVM 类、JVM 接口、JVM 类型和 JVM 方法相互通信。
在这两种情况下,这些平台原语看起来一点也不像 Python 或 Ruby 对象。
对于 JRuby,Jython 只是另一个 Java 程序。对于 Jython,JRuby 只是另一个 Java 程序。
例如:在 Ruby 中,您可以随时动态地添加、删除和重新定义方法。在JVM上,可以动态添加和删除的最小代码单元是一个类。因此,Ruby 方法实际上并不表示为 Java 方法。它表示为 Java 类。从逻辑上讲,具有几个方法的 Ruby 对象表示为没有方法的 Java 对象,只有一个 Dictionary<String, RubyMethod> 字段。 IOW:它在 Java 中完全不可用,而且,因为从 JRuby 的角度来看,Jython 只是 Java,所以它也不能从 Jython 中使用。
现在,有 种方法可以让这一切变得更好。您可以使用实际的 Java 类型在两者之间进行通信——这两种实现都与 Java 具有很好的互操作性。因此,您可以使用 Ruby 和 Python 中的 Java Map,而不是将 Ruby 哈希传递给 Python 或将 Python 字典传递给 Ruby。但请注意,这要求您的 Ruby 和 Python 代码都是专门为在 JVM 上工作而编写的。 IOW:你不能只使用你在网上找到的任何 Python 或 Ruby 库,这就是你要问的。
@duncan 在他的回答中提到了另一种可能性:将 Jython 或 JRuby 作为脚本引擎嵌入到您的 Ruby 或 Python 应用程序中。但同样,这并不能真正回答您关于使用 Ruby 中的任意 Python 库的问题,反之亦然。
那么,这里有什么问题?
问题在于,为了让两个运行时进行通信,它们需要使用相同的“语言”。在这种特殊情况下,两个运行时的唯一共同语言是 Java,或者说是 Java 的一个严重残缺的子集。
所以,我们需要找到一种共同语言。定义这种语言的一种方法是让两个运行时都了解彼此的元对象协议 (MOP)。
MOP 基本上是语言对象模型的对象模型。嗯,这很令人困惑,因为我们使用“对象模型”这个词来表示两个不同的东西。让我换个说法:
MOP 基本上是语言对象系统的领域模型。就像银行系统的域模型包含代表现实世界客户、账户、余额、分类帐等的对象,以及代表现实世界行动(如汇款、取款等)的方法,MOP 包含代表的对象表示语言操作的语言类、方法、变量、对象和方法,例如查找变量、调用方法、从类继承、构造类的实例。
通常,每个运行时都将其 MOP 保持为私有,并且每个运行时都有自己的 MOP。
如果 JRuby 和 Jython 彼此公开他们的 MOP 并理解彼此的 MOP(或者,更好的是:他们将自己的 MOP 公开给 JVM 并且都使用了相同的 MOP),那么您可以将其中一个疯狂的 JRuby 方法包传递给 Jython,它就会知道如何找到属于该对象的方法以及如何调用它们,因为它可以询问 JRuby 的 MOP 是如何做到的。
实际上有一个项目可以为 JVM 创建这样的 MOP:dynalang MOP 是一个用于在 JVM 上运行的动态语言的共享标准化 MOP 项目。它由 Mozilla Rhino ECMAScript 引擎的维护者 Attila Szegedi 创建。目前,没有一个大型语言实现使用它,但至少 Rhino、JRuby、Jython 和 Groovy 之间正在进行协作,以确保 dynalang 足够通用,可以支持所有不同语言的对象模型。
如果您想先睹为快,了解具有这种共享 MOP 的世界会是什么样子,您可以查看 Microsoft 的动态语言运行时 (DLR)。 DLR 仅包含这样一个 MOP 和支持 DLR 的所有运行时(除了常见的问题,例如 IronRuby、IronPython、IronJS 和 IronScheme,现在还包括 C# 4 和 Visual Basic.NET 10) 几乎可以无缝地相互操作。
另一个类似的平台是Parrot Virtual Machine,它专门设计用于允许多种动态语言在同一个运行时平台上互操作。有可用的 Python (Pynie) 和 Ruby (Cardinal) 的实现,但尤其是 Cardinal 距离远程完整的 Ruby 实现还有很长的路要走。