1

My python script is like this:

def main():
  ret = [1, 2]
  return ret

and I call the python script from ruby like this:

output = system("python script.py")

print output

However the value of output is true. I want to get [1, 2]. My question is how I can get the return value of the python script?

3 Answers 3

4

First, have your Python script print the value rather than returning it, or add print main() at the bottom so the return value of main() gets printed.

Second, on the Ruby side, execute it with backticks rather than the system() function, like this:

output = `python script.py`

This captures the output of the Python script as a string. If you want it as a Ruby array, you'll need to parse it. Ruby's array literal syntax is similar to Python's list literal syntax, so this is not as tough as it might seem. If you can find something that parses strings into Ruby arrays (besides eval() because it's dangerous) you should be covered. Problems will arise when you have things besides simple types, None, or potentially strings with escapes in them.

I am more a Python guy than a Ruby guy, but Ruby doesn't seem to have anything like Python's ast.literal_eval (a safe eval() that only accepts literals) in its standard library. However, I did find parsr which appears to be exactly that.

If the Python list literals you're getting aren't valid Ruby, you can use JSON as the interchange format:

# Python side
import json, sys
json.dump(main(), sys.stdout)

# Ruby side
require 'json'
output = JSON.parse(`python script.py`)
Sign up to request clarification or add additional context in comments.

Comments

3

This is python test.py

import sys

def main():
  ret = [1, 2]
  print >> sys.stdout, ret 

main()

This is ruby code test.rb

require 'open3'
require 'json'

stdin, stdout, stderr = Open3.popen3("python test.py")
stdout.each do |ele|
  p ele #=> "[1, 2]\n"
  p JSON.parse(ele) #=> [1, 2]
end

Then execute ruby script in shell

ruby test.rb 

You need by the stdout to get the python return value in ruby script, and by the some ugly tips, I didn't find the other better way in this time, but the code can work and accept the python return value at least now, maybe you can try it and search the better solution continuously.

2 Comments

printgoes to standard output by default in Python.
@kindall, you're right, print >> sys.stdout, ret can change to print ret
1

If you have the Python script print its result, then then it will be captured in result. This is the "standard out" i.e. StdOut, it's what ruby's system reads.

You also need to have the python script actually call the method when it's run from the command line.

edit

My mistake, use backticks instead of system. And rather than using regex or string manipulation to pass data between python and ruby, use a standard serialization format like json or yaml.

1 Comment

From what I can tell system() returns true, false, or nil based on the return code of the command—not the output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.