2010-05-02 10 views
11

Muy-probablemente una pregunta tonta, ya que no sé mucho acerca de Java/Jython/JRuby/código de bytes, pero ..¿Utiliza JRuby/Jython para la interoperabilidad Ruby/Python?

me encontré con _why's unholy hoy de nuevo .. Se le permite a la salida de código de bytes de código Ruby Python ... Básicamente permitiéndoles producir el mismo bytecode ...

Jython genera bytecode Java, al igual que JRuby ... Dado que ambos compilan en el mismo bytecode, ¿esto significa que potencialmente podría usar cualquier biblioteca Python de Ruby y Ruby? bibliotecas de Python?

+0

+1 para una pregunta interesante ... – ChristopheD

+1

BTW: esa "VM mítica que ejecuta todos los idiomas" que se menciona al final del impío README, * es * la máquina virtual Parrot que mencioné en mi respuesta. Y afortunadamente, ahora ya no es mítico: la gran versión 1.0.0 fue hace más de un año, y desde entonces, el equipo Parrot ha producido una versión estable por mes como mecanismo de relojería, llegando a (actualmente) 2.3.0 hace dos semanas . Por supuesto, esto no significa que realmente haya un * compilador * para todos y cada uno de los idiomas (en particular, el compilador Cardinal Ruby está lejos de estar listo para la producción), solo que la VM existe y es estable. –

Respuesta

7

No, eso no funcionará. Al menos no de la manera que crees que sería.

La interoperabilidad entre Jython y JRuby funciona de la misma manera que entre CPython y YARV: ambos se ejecutan en la misma plataforma, por lo que pueden comunicarse entre sí utilizando esa plataforma.

En el caso de CPython y YARV, que la plataforma es C/POSIX, para que puedan comunicarse entre sí utilizando estructuras C, int s, char* s y llamadas a funciones C. En el caso de Jython y JRuby, esa plataforma es la JVM, por lo que pueden comunicarse entre sí utilizando objetos JVM, clases JVM, interfaces JVM, tipos JVM y métodos JVM.

En ambos casos, las primitivas de la plataforma se ven como como objetos Python o Ruby.

Para JRuby, Jython es simplemente otro programa de Java. Para Jython, JRuby es solo otro programa de Java.

Por ejemplo: en Ruby, puede agregar, eliminar y redefinir métodos dinámicamente en cualquier momento. En la JVM, la unidad de código más pequeña que se puede agregar y eliminar dinámicamente es una clase. Entonces, un método de Ruby en realidad no está representado como un método de Java.Se representa como Java clase. Y lógicamente, un objeto Ruby con un par de métodos se representa como un objeto Java sin métodos, solo un campo Dictionary<String, RubyMethod>. IOW: es totalmente inutilizable desde Java, y, desde el punto de vista de JRuby, Jython es solo Java, también inutilizable desde Jython.

Ahora, hay son maneras de hacer esto un poco mejor. Puede usar tipos de Java reales para comunicarse entre los dos   –, ambas implementaciones tienen una gran interoperabilidad con Java. Por lo tanto, en lugar de pasar un hash Ruby a Python o un diccionario Python a Ruby, usaría Java Map de Ruby y Python. Pero tenga en cuenta que esto requiere que ambos su código de Ruby y Python estén específicamente escritos para trabajar en la JVM. IOW: no puedes usar cualquier biblioteca de Python o Ruby que encuentres en la web, que es lo que estás preguntando.

Otra posibilidad es la que menciona @duncan en su respuesta: inserte Jython o JRuby como un motor de scripting en su aplicación Ruby o Python. Pero, de nuevo, esto realmente no responde a su pregunta sobre el uso de bibliotecas de Python arbitrarias de Ruby o viceversa.

Entonces, ¿cuál es el problema aquí?

El problema es que para que los dos tiempos de ejecución se comuniquen, necesitan hablar el mismo "idioma". Y en este caso particular, el único lenguaje que los dos tiempos de ejecución tienen en común es Java, o más bien un subconjunto gravemente dañado de Java.

Por lo tanto, tenemos que encontrar un lenguaje común. Una forma de definir dicho lenguaje sería que ambos tiempos de ejecución entiendan el Protocolo Meta-Objeto (MOP) de los demás.

Un MOP es básicamente un modelo de objetos para el modelo de objetos del idioma. Um, eso es confuso porque usamos la palabra "modelo de objeto" para referirnos a dos cosas diferentes. Permítanme reformular eso:

Un MOP es básicamente un modelo de dominio para el sistema de objetos del idioma. Al igual que un modelo de dominio para un sistema bancario contiene objetos que representan clientes del mundo real, cuentas, balances, libros mayores, etc., y métodos que representan acciones del mundo real como transferencias monetarias, retiros, etc., un MOP contiene objetos que representan clases de lenguaje, métodos, variables, objetos y métodos que representan acciones de lenguaje como buscar una variable, llamar a un método, heredar de una clase, construir una instancia de una clase.

Normalmente, cada tiempo de ejecución mantiene su MOP en privado, y cada tiempo de ejecución tiene su propio MOP.

Si JRuby y Jython expuestos sus MOSes entre sí y entender MOSes del otro (o, mejor aún: expusieron sus MOSes a la JVM y ambos utilizan la misma MOP), entonces se podría pasar a uno de los El loco método de JRuby se empaqueta en Jython, y sabría cómo encontrar los métodos que pertenecen a ese objeto y cómo llamarlos, ya que solo le puede preguntar a JRuby's MOP cómo hacerlo.

En realidad, existe un proyecto para crear una MOP para la JVM: el dynalang MOP es un proyecto para una MOP estandarizada y compartida para lenguajes dinámicos que se ejecutan en la JVM. Fue creado por Attila Szegedi, el mantenedor del motor Mozilla Rhino ECMAScript. Por el momento, ninguna de las grandes implementaciones de lenguaje lo usa, pero existe una colaboración entre, al menos, Rhino, JRuby, Jython y Groovy para asegurarse de que dynalang sea lo suficientemente genérico como para admitir todos los modelos de objetos de diferentes idiomas.

Si desea obtener un adelanto de cómo sería un mundo con un MOP compartido, puede echar un vistazo a Dynamic Language Runtime (DLR) de Microsoft. El DLR contiene solo un MOP y todos los tiempos de ejecución que admiten el DLR (que, además de los sospechosos habituales como IronRuby, IronPython, IronJS y IronScheme ahora también incluye C# 4 y Visual Basic.NET 10) puede interoperar casi sin problemas con cada uno otro.

Otra plataforma similar es la Parrot Virtual Machine, que fue diseñada específicamente para permitir que varios lenguajes dinámicos interactúen en la misma plataforma de tiempo de ejecución. Hay implementaciones de Python (Pynie) y Ruby (Cardinal) disponibles, pero especialmente Cardinal aún está muy lejos de ser una implementación de Ruby remotamente completa.

5

Hay dos maneras de hacerlo. Ambos ofrecen la capacidad de compilar código de forma estática y producir una clase real de Java a partir del script. Jython AFAIK en este caso genera código fuente de Java y luego llama a javac, a través de un script jythonc. Pero esto requiere compilación.

Para ambos intérpretes, puede llamar al código Java desde scripts, y puede incrustar el intérprete en una aplicación Java.

Por ejemplo, para llamar a Java desde Python:

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

Para incrustar JRuby intérprete de Java, que puede hacer (nota, hay una manera basada JSR223 también, este es el núcleo de una):

package vanilla; 

import org.jruby.embed.ScriptingContainer; 

public class HelloWorld { 

    private HelloWorld() { 
     ScriptingContainer container = new ScriptingContainer(); 
     container.runScriptlet("puts Hello world"); 
    } 

    public static void main(String[] args) { 
     new HelloWorld(); 
    } 

se podría hacer lo mismo desde Jyton (supongo que tendría que dar los caminos JRuby correctamente):

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

Lo mismo se puede hacer al revés.

No obtendrá todo el rubd stdlib exportado al intérprete de python haciendo una importación. Tendría que precompilar el stdlib de ruby ​​al bytecode por adelantado.

Sin embargo, con la técnica descrita anteriormente y agregando un par de scripts de ayuda e interfaces definidas, puede puentear la funcionalidad específica de un idioma a otro.

Cuestiones relacionadas