Eval. get the console result into a variable

I’m creating a web service using Sinatra to run ruby code, so for that
I’m using something like:

begin
eval(code)
rescue Exception => resRun
end

but I need to get access to the result of the code run in the console…
so if code is something like:
puts “example”

I want to get the output “example” in a variable

How is it possible to do it?

Hi,

The kernel methods “print”, “puts” etc. actually call $stdout.write and
$stdout.puts. So you could simply create your own object with a write
and puts method and (temporarily) change $stdout to this object:

class OutputCollector

attr_reader :content

def write x
@content += x.to_s
end

def puts x
write x.to_s + “\n”
end

def initialize
@content = ‘’
end

end

this changes $output to an instance of OutputCollector, executes the

block (all output will be written to the OutputCollector), changes

$stdout back to the default value (given by STDOUT) and returns the

collected output

def catch_output
coll = OutputCollector.new
$stdout = coll
yield
$stdout = STDOUT
coll.content
end

caught = catch_output do
print ‘abc’
print 123
end

show collected output

p caught

Of course, you should be careful when evaluating user code. I would at
least create a new Thread with an appropriate value of $SAFE.

Not working in my case since what we have inside is an eval with a
testcase inside

Jan E. wrote in post #1051635:

Hi,

The kernel methods “print”, “puts” etc. actually call $stdout.write and
$stdout.puts. So you could simply create your own object with a write
and puts method and (temporarily) change $stdout to this object:

What do you mean? What isn’t working?

Did you try something simple like

caught = catch_output do
eval ‘print 1’
end
p caught

If this works (it should), then there’s probably something wrong with
the string you evaluate. Does it even have output?

Jan E. wrote in post #1051815:
I didn’t get anything

What do you mean? What isn’t working?

Thanks for the help… but it is more difficult like it looks like
so i’m gonna do it other way… putting the code in a file and then
calling resRun= ruby #{fileNameRuby}

and in case resRun is empty means that there was an error in the code so
i have to do it like resRun=eval(code)

Thanks for your help :slight_smile:

Jan E. wrote in post #1051820:

Did you try something simple like

caught = catch_output do
eval ‘print 1’
end
p caught

If this works (it should), then there’s probably something wrong with
the string you evaluate. Does it even have output?