使用JRuby/Jython实现Ruby/Python互操作性? [英] Using JRuby/Jython for Ruby/Python interoperability?

查看:74
本文介绍了使用JRuby/Jython实现Ruby/Python互操作性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能是一个愚蠢的问题,因为我对Java/Jython/JRuby/bytecode不太了解,但是..

今天我又偶然发现了 _为什么不正确.它允许您从Ruby代码输出Python字节码.基本上允许它们产生相同的字节码.

Jython会输出Java字节码,就像JRuby一样..由于它们都编译为相同的字节码,这是否意味着您可能会使用Ruby中的任何Python库以及Python中的Ruby库?

解决方案

不,这不起作用.至少不是您想的那样.

Jython和JRuby之间的互操作性与CPython和YARV之间的互操作性相同:它们都在同一平台上运行,因此它们可以使用该平台相互通信.

对于CPython和YARV,该平台是C/POSIX,因此它们可以使用C结构,int s,char* s和C函数调用相互通信.对于Jython和JRuby,该平台就是JVM,因此它们可以使用JVM对象,JVM类,JVM接口,JVM类型和JVM方法相互通信.

在这两种情况下,这些平台原语看上去都不像Python或Ruby对象.

对于JRuby,Jython只是另一个Java程序.对Jython而言,JRuby只是另一个Java程序.

例如:在Ruby中,您可以随时动态地添加,删除和重新定义方法.在JVM上,可以动态添加和删除的最小代码单元是一个类.因此,Ruby方法实际上并不表示为Java方法.它表示为Java class .从逻辑上讲,具有几个方法的Ruby对象表示为没有方法的Java对象,只是一个Dictionary<String, RubyMethod>字段. IOW:它在Java中是完全不可用的,并且,从JRuby的角度来看,Jython只是Java,因此在Jython中也是不可用的.

现在,有 种方法可以使它变得更好一点.您可以使用实际的Java类型在两者之间进行通信.两种实现都具有与Java的良好互操作性.因此,您无需将Ruby哈希传递给Python或将Python字典传递给Ruby,而应同时使用Ruby和Python中的Java Map.但是请注意,这要求两者都必须将您的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具有足够的通用性,可以支持所有不同语言的对象模型. /p>

如果您想先睹为快,拥有这样一个共享MOP的世界将是什么样子,可以看看Microsoft的动态语言运行时(DLR). DLR包含这样的MOP和所有支持DLR的运行时(除了 IronRuby 这样的常见可疑对象之外) , IronPython IronJS IronScheme 现在还包括C#4和Visual Basic.NET 10),它们几乎可以无缝地互操作.

另一个类似的平台是 Parrot虚拟机,该平台专门用于允许多种动态语言在同一平台上进行互操作运行时平台.有Python( Pynie )和Ruby(_why's unholy again today.. It allows you to output Python bytecode from Ruby code.. Basically allowing them to produce the same bytecode..

Jython outputs Java bytecode, as does JRuby.. Since these both compile to the same bytecode, does this mean you could potentially use any Python library from Ruby, and Ruby libraries from Python?

解决方案

No, that won't work. At least not the way you think it would.

Interoperability between Jython and JRuby works the same way as between CPython and YARV: they both run on the same platform, so they can communicate with each other using that platform.

In the case of CPython and YARV, that platform is C/POSIX, so they can communicate with each other using C structs, ints, char*s and C function calls. In the case of Jython and JRuby, that platform is the JVM, so they can communicate with each other using JVM objects, JVM classes, JVM interfaces, JVM types and JVM methods.

In both cases, those platform primitives look nothing like Python or Ruby objects.

To JRuby, Jython is just yet another Java program. To Jython, JRuby is just another Java program.

For example: in Ruby, you can add, remove and redefine methods dynamically at any moment. On the JVM, the smallest unit of code that can be dynamically added and removed is a class. So, a Ruby method is actually not represented as a Java method. It is represented as a Java class. And logically, a Ruby object with a couple of methods is represented as a Java object with no methods, just a Dictionary<String, RubyMethod> field. IOW: it's totally unusable from Java, and, since from JRuby's point of view Jython is just Java, it's also unusable from Jython.

Now, there are ways to make this a little bit better. You could use actual Java types to communicate between the two – both implementations have great interoperability with Java. So, instead of passing a Ruby hash to Python or a Python dictionary to Ruby, you would use a Java Map from both Ruby and Python. But note that this requires that both your Ruby and Python code are specifically written to work on the JVM. IOW: you cannot just use any Python or Ruby library you find on the web, which is what you are asking about.

Another possibility is the one mentioned by @duncan in his answer: embed Jython or JRuby as a scripting engine into your Ruby or Python application. But again, this doesn't really answer your question about using arbitrary Python libraries from Ruby or vice versa.

So, what is the problem here?

The problem is that in order for the two runtimes to communicate, they need to speak the same "language". And in this particular case, the only language that the two runtimes have in common, is Java, or rather a severely crippled subset of Java.

So, we need to find a common language. One way to define such a language would be for both runtimes to understand each other's Meta-Object Protocol (MOP).

A MOP is basically an object model for the language's object model. Um, that's confusing because we use the word "object model" to mean two different things. Let me rephrase that:

A MOP is basically a domain model for the language's object system. Just like a domain model for a banking system contains objects that represent real-world customers, accounts, balances, ledgers and so on, and methods that represent real-world actions like money transfers, withdrawals and so on, a MOP contains objects that represent language classes, methods, variables, objects and methods that represent language actions like looking up a variable, calling a method, inheriting from a class, constructing an instance of a class.

Normally, every runtime keeps its MOP private, and every runtime has its own MOP.

If JRuby and Jython exposed their MOPs to each other and understood each other's MOPs (or, even better yet: they exposed their MOPs to the JVM and both used the same MOP), then you could pass one of those crazy JRuby method bags to Jython, and it would know how to find the methods that belong to that object and how to call them, because it can just ask JRuby's MOP how to do it.

There is actually a project to create just such a MOP for the JVM: the dynalang MOP is a project for a shared, standardized MOP for dynamic languages running on the JVM. It was created by Attila Szegedi, the maintainer of the Mozilla Rhino ECMAScript engine. At the moment, none of the big language implementations uses it, but there is collaboration going on between at least Rhino, JRuby, Jython and Groovy to make sure that dynalang is generic enough that it can support all of the different language's object models.

If you want a sneak peek at what a world with such a shared MOP would look like, you can take a look at Microsoft's Dynamic Language Runtime (DLR). The DLR contains just such a MOP and all runtimes which support the DLR (which, in addition to the usual suspects such as IronRuby, IronPython, IronJS and IronScheme now also includes C# 4 and Visual Basic.NET 10) can almost seamlessly interoperate with each other.

Another similar platform is the Parrot Virtual Machine, which was specifically designed to allow multiple dynamic languages to interoperate on the same runtime platform. There are implementations of Python (Pynie) and Ruby (Cardinal) available, but especially Cardinal is still very far from being even a remotely complete Ruby implementation.

这篇关于使用JRuby/Jython实现Ruby/Python互操作性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆