使用JRuby/Jython实现Ruby/Python的互操作性?

2024-06-16 10:43:58 发布

您现在位置:Python中文网/ 问答频道 /正文

很可能是个愚蠢的问题,因为我对Java/Jython/JRuby/bytecode知之甚少,但是。。在

今天我又偶然发现了_why's unholy。。它允许您从Ruby代码输出Python字节码。。基本上允许他们产生相同的字节码。。在

Jython输出Java字节码,JRuby也是。。因为这两者都编译成相同的字节码,这是否意味着您可以使用Ruby中的任何Python库和Python中的Ruby库?在


Tags: 代码字节jythonjavaruby编译成bytecodewhy
2条回答

有两种方法。两者都提供了静态编译代码和从脚本生成真正的Java类的能力。在本例中,jythonafaik生成Java源代码,然后通过jythonc脚本调用javac。但这需要汇编。在

对于这两个解释器,您可以从脚本调用Java代码,并且可以将解释器嵌入到Java应用程序中。在

例如,要从Python调用Java:

>>> from java.util import Random
>>> r = Random()
>>> r.nextInt()
501203849

要在Java中嵌入JRuby解释器,可以这样做(注意,也有一种基于JSR223的方法,这是核心方法):

^{pr2}$

从Jyton也可以这样做(我想您需要正确地给出jruby路径):

import org.jruby.embed.ScriptingContainer
container = ScriptingContainer()
container.runScriptlet("puts Hello world")

同样的事情也可以反过来做。在

通过导入不会将整个ruby stdlib导出到python解释器。您需要预先将ruby的stdlib预编译为字节码。在

然而,使用上述技术,并添加一些助手脚本和定义的接口,您可以将特定功能从一种语言过渡到另一种语言。在

不,那不行。至少不是你想的那样。在

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>字段。low:它在Java中是完全不可用的,而且,从JRuby的角度来看Jython只是Java,它在Jython中也是不可用的。在

现在,有一些方法可以让这一切变得更好。您可以使用实际的Java类型在两者之间进行通信–这两个实现都与Java具有很好的互操作性。因此,您将使用Ruby和Python中的JavaMap,而不是将Ruby散列或Python字典传递给Ruby。但请注意,这需要您的Ruby和Python代码都是专门为在JVM上工作而编写的。low:你不能只使用你在网上找到的任何Python或Ruby库,这正是你所要问的。在

另一种可能是@duncan在回答中提到的一种可能性:将Jython或JRuby作为脚本引擎嵌入到Ruby或Python应用程序中。但是,这并不能真正回答您关于使用Ruby中的任意Python库的问题,反之亦然。在

那么,这里有什么问题?在

问题是为了让两个运行时进行通信,它们需要使用相同的“语言”。在这个特定的例子中,这两个运行时唯一的共同语言是Java,或者更确切地说是Java的一个严重残缺的子集。在

所以,我们需要找到一种共同的语言。定义这种语言的一种方法是让两个运行时都能理解彼此的元对象协议(Meta Object Protocol,MOP)。在

MOP基本上是语言对象模型的对象模型。嗯,这很令人困惑,因为我们用“对象模型”这个词来表示两个不同的东西。让我重新表述一下:

MOP基本上是语言对象系统的领域模型。就像银行系统的域模型包含表示真实世界客户、账户、余额、分类账等的对象,以及表示现实世界操作(如转账、取款等)的方法一样,MOP包含表示语言类、方法、变量、对象和表示语言的方法的对象像查找变量、调用方法、从类继承、构造类实例等操作。在

通常,每个运行时都将其MOP私有化,并且每个运行时都有自己的MOP。在

如果JRuby和Jython将它们的MOP公开给对方并理解对方的MOP(或者,更好的是:他们将MOP暴露给JVM,并且都使用相同的MOP),那么您可以将这些疯狂的JRuby方法包之一传递给Jython,Jython就会知道如何找到属于该对象的方法以及如何调用它们,因为它可以问JRuby的MOP怎么做。在

实际上有一个项目可以为JVM创建这样一个MOP:dynalang MOP是为在JVM上运行的动态语言的共享、标准化MOP。它是由Mozilla Rhino ECMAScript引擎的维护者Atila Szegedi创建的。目前,没有一个大型语言实现使用它,但是至少Rhino、JRuby、Jython和Groovy之间正在进行协作,以确保dynalang足够通用,能够支持所有不同语言的对象模型。在

如果你想要一窥拥有这样一个共享MOP的世界将会是什么样子,你可以看看微软的动态语言运行时(DLR)。DLR只包含这样一个MOP和所有支持DLR的运行时(除了常见的疑点,如IronRubyIronPythonIronJS和{a5}之外,现在还包括C#4和Visual基本.NET10) 几乎可以无缝地互操作。在

另一个类似的平台是Parrot Virtual Machine,它是专门为允许多个动态语言在同一个运行时平台上进行互操作而设计的。Python(Pynie)和Ruby(Cardinal)的实现是可用的,但尤其是Cardinal还远远没有成为一个远程完整的Ruby实现。在

相关问题 更多 >