Используя JRuby/Jython для совместимости Ruby/Python?

Вполне вероятно глупый вопрос, поскольку я не знаю много о Java/Jython/JRuby/bytecode, но..

Я споткнулся через _why, безобразный снова сегодня.. Это позволяет Вам производить байт-код Python из кода Ruby.. В основном позволяя им произвести тот же байт-код..

Выходной байт-код Java Jython, как делает JRuby.. Начиная с них обоих компиляция к тому же байт-коду это означает, что Вы могли потенциально пользоваться какой-либо библиотекой Python от Ruby и библиотеками Ruby из Python?

11
задан dbr 2 May 2010 в 09:25
поделиться

2 ответа

Нет, это не сработает. По крайней мере, не так, как вы думаете.

Взаимодействие между 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 . И логически объект Ruby с парой методов представлен как объект Java без методов, только поле Dictionary . IOW: он совершенно непригоден для использования из Java, и, поскольку с точки зрения JRuby, Jython - это просто Java, его также нельзя использовать из Jython.

Есть способов сделать это немного лучше.Вы можете использовать реальные типы Java для связи между ними - обе реализации обладают отличной совместимостью с Java. Итак, вместо передачи хэша Ruby в Python или словаря Python в Ruby, вы должны использовать Java Map как из Ruby, так и из Python. Но обратите внимание, что для этого требуется, чтобы и ваш код Ruby и Python были специально написаны для работы на JVM. IOW: вы не можете просто использовать любую библиотеку Python или Ruby, которую найдете в Интернете, о чем вы спрашиваете.

Другой вариант, упомянутый @duncan в его ответе: встроить Jython или JRuby в качестве механизма сценариев в ваше приложение Ruby или Python. Но опять же, это не совсем ответ на ваш вопрос об использовании произвольных библиотек Python из Ruby или наоборот.

Итак, в чем проблема?

Проблема в том, что для того, чтобы две среды выполнения могли взаимодействовать, они должны говорить на одном «языке». И в этом конкретном случае единственный язык, который является общим для двух сред выполнения, - это Java, или, скорее, сильно урезанное подмножество Java.

Итак, нам нужно найти общий язык. Один из способов определить такой язык - чтобы обе среды выполнения понимали протокол метаобъектов (MOP) друг друга.

MOP - это, по сути, объектная модель для объектной модели языка. Гм, это сбивает с толку, потому что мы используем слово «объектная модель» для обозначения двух разных вещей. Позвольте мне перефразировать следующее:

MOP - это, по сути, модель предметной области для объектной системы языка.Точно так же, как модель предметной области для банковской системы содержит объекты, которые представляют реальных клиентов, счета, балансы, бухгалтерские книги и т. Д., И методы, которые представляют реальные действия, такие как денежные переводы, снятие средств и т. Д., MOP содержит объекты, которые представляют языковые классы, методы, переменные, объекты и методы, которые представляют языковые действия, такие как поиск переменной, вызов метода, наследование от класса, создание экземпляра класса.

Обычно каждая среда выполнения сохраняет свою MOP закрытой, и каждая среда выполнения имеет свою собственную MOP.

Если JRuby и Jython открывали свои MOP друг другу и понимали MOP друг друга (или, что еще лучше: они открывали свои MOP для JVM, и оба использовали одну и ту же MOP), то вы могли бы пройти один из этих сумасшедших методов JRuby для Jython, и он будет знать, как найти методы, принадлежащие этому объекту, и как их вызвать, потому что он может просто спросить MOP JRuby, как это сделать.

На самом деле существует проект по созданию именно такой MOP для JVM: dynalang MOP - это проект для совместно используемой стандартизированной MOP для динамических языков, работающих на JVM. Он был создан Аттилой Сегеди, разработчиком движка Mozilla Rhino ECMAScript. На данный момент ни одна из крупных языковых реализаций не использует его, но, по крайней мере, между Rhino, JRuby, Jython и Groovy ведется совместная работа, чтобы убедиться, что dynalang достаточно универсален, чтобы поддерживать все объектные модели разных языков.

Если вы хотите взглянуть на то, как будет выглядеть мир с такой общей MOP, вы можете взглянуть на Microsoft Dynamic Language Runtime (DLR). DLR содержит именно такую ​​MOP и все среды выполнения, которые поддерживают DLR (которые, помимо обычных подозреваемых, таких как IronRuby , IronPython , IronJS и IronScheme теперь также включает C # 4 и Visual Basic. NET 10) могут почти беспрепятственно взаимодействовать друг с другом.

Другой подобной платформой является виртуальная машина Parrot , которая была специально разработана, чтобы позволить нескольким динамическим языкам взаимодействовать на одной платформе времени выполнения. Доступны реализации Python ( Pynie ) и Ruby ( Cardinal ), но особенно Cardinal все еще очень далек от того, чтобы быть даже удаленно завершенной реализацией Ruby.

7
ответ дан 3 December 2019 в 09:19
поделиться

Это можно сделать двумя способами. Оба предлагают возможность статической компиляции кода и создания реального класса Java из сценария. Jython AFAIK в этом случае генерирует исходный код Java, а затем вызывает javac через скрипт jythonc. Но для этого требуется компиляция.

Для обоих интерпретаторов вы можете вызывать код Java из сценариев, и вы можете встроить интерпретатор в приложение Java.

Например, чтобы вызвать Java из Python:

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

Чтобы встроить интерпретатор JRuby в Java, вы можете сделать (обратите внимание, есть также способ на основе JSR223, он является основным):

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();
    }

Вы можете сделать то же самое от Jyton (я думаю, вам нужно будет правильно указать пути jruby):

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

То же самое можно сделать и в другом направлении.

Вы не сможете экспортировать всю ruby ​​stdlib в интерпретатор python, выполнив импорт. Вам нужно будет заранее скомпилировать stdlib ruby ​​в байт-код.

Однако с помощью описанной выше техники и добавления пары вспомогательных сценариев и определенных интерфейсов вы можете связать определенные функции с одного языка на другой.

5
ответ дан 3 December 2019 в 09:19
поделиться