And now for something completely different—executing Python code, from Ruby. Useful for accessing Python standard libraries, re-using code already written in Python without having to port it to Ruby, calculating the air-speed velocity of an unladen swallow, or just for fun.
Install the pycall gem
Make sure you have the pycall gem installed:
gem install pycall
Alternatively add the gem to your Gemfile and install it via bundler.
Check you have Python installed
Unsurprisingly to execute Python code you’ll also need Python installed! You can check what version of Python you are running with the following command:
If you don’t have Python installed you can download it from python.org or install it with your system package manager (recommended).
Executing Python functions
To get started in your Ruby script you need to require the pycall gem and include the
PyCall::Import module. You can then import a Python module using the
pyimport method and call its functions directly from Ruby. For example:
require 'pycall/import' include PyCall::Import pyimport :os p os.uname pyimport :mimetypes p mimetypes.guess_type('index.html') pyimport :math p math.degrees(math.pi / 2)
Built-in functions are callable on the __builtin__ module, which is exposed in Ruby as
PyCall.builtins and doesn’t need to be explicitly imported. For example:
require 'pycall' p PyCall.builtins.sum([1, 2, 3, 4])
Some Python types like booleans, numerics, and strings are converted back to their equivalent Ruby types. Other types like lists and tuples are returned as wrapper classes, which you might want to explicitly convert back to Ruby types.
Executing Python code
PyCall.exec method to execute Python code, and the
PyCall.eval method to evaluate Python expressions. For example:
require 'pycall' PyCall.exec 'def double(x): return x * 2' p PyCall.eval('double(123)') p PyCall.eval('(1, 2, 3)') p PyCall.eval('[pow(2, x) for x in xrange(10)]')
This might be useful for constructing Python data structures or implementing algorithms that are more easily expressed in Python. Same as with eval in Ruby: watch out for issues with escaping, and don’t eval code you don’t trust.
Using a different Python version
By default pycall will use the default python on your system. You can specify a different version of Python by setting the PYTHON environment variable or calling
PyCall.init with the path or basename of the python you want to use. For example:
require 'pycall' PyCall.init('python3') p PyCall::PYTHON_VERSION
Python 3 recommended where possible. 🐍