I’m looking to call Python code from Ruby. There are a few existing tools to do this and a few questions on this site recommending http://rubypython.rubyforge.org/, which works by embedding the Python interpreter in Ruby. I’m working on an app that uses libraries unique to Python (namely graph-tool, which I have reasons for using over, say RGL), but the final project is in Rails so having Ruby code do the controlling work would be ideal. I want it to be speedy so I’m using PyPy. Is there a way to get the PyPy interpreter embedded in Ruby code, or to make the Python interpreter in rubypython run PyPy?
I’m looking to call Python code from Ruby. There are a few existing tools
Share
No. Well, not without a lot of work.
First, RubyPython doesn’t really include an embedded Python interpreter; it just wraps the interpreter at runtime. As shown in the docs, you can run it with any Python you want, e.g.:
So, what happens when you try?
Unfortunately, it requires CPython 2.4-2.7. It doesn’t work with CPython 3.x, PyPy, Jython, etc. Again, from the docs:
Without looking at the code, I’m guessing rubypython is using rubyffi to either:
* Wrap the CPython embedding APIs, or
* Directly call CPython VM internals via its dll/so/dylib exports.
If it’s the former, the project might be doable, but still a lot of work. PyPy doesn’t support CPython’s embedding APIs. If it had its own embedded APIs, you could potentially rewrite rubypython’s lower level to wrap those instead, and leave the higher-level code alone. But embedding PyPy at all is still a work in progress, (See http://mail.python.org/pipermail/pypy-dev/2012-March/009661.html for the state of affairs 6 months ago.) So, you’d need to first help get PyPy embedding ready for prime time and stable, and then port the lower level of rubypython to use the different APIs.
If it’s the latter, you’re pretty much SOL. PyPy will never support the CPython internals, and much of what’s internal for CPython is actually written in RPython or Python and then compiled for PyPy, so it’s not even possible in principle. You’d have to drastically rewrite all of rubypython to find some way to make it work, instead of just porting the lower level.
One alternative is to port Ruby to RPython and use PyPy to build a Ruby interpreter and a Python interpreter that can talk to each other at a higher level; then, writing something like rubypython for PyRuby and PyPy would be trivial. But that first step is a doozy.