Ruby closing program window on Windows 7 - ruby

I've download Ruby using rubyinstaller. Apps closed itself after finishing executing, so i put gets at the end of it - it works, but if there is an error it closes, and I have problem with debugging. How can i prevent this?

Probably the best way is to run your Ruby program from console (command line).
An alternative hack is to wrap your main program in an exception handler:
begin
... your code here ...
rescue => exc
puts "#{exc.class}: #{exc}" # write exception message
puts exc.backtrace.join "\n" # write backtrace
gets # wait for Return
end

Related

Capture failures when using Ruby open3 standard library

I'm running an external command using the Open3.popen2e function. The external command fails spectacularly halfway through. Unfortunately this also kills my ruby process that is using popen2e. What is the reason, and how can I avoid?
begin
Open3.popen2e("node mynode.js") do |i, oe|
oe.each do |ln|
puts ln.chomp
end
end
rescue => exception
puts exception.message
end
Using ruby 2.5.1 on Ubuntu
Not sure about the reason, but a non-StandardError may be raised. So, what about changing your rescue to:
rescue Exception => exception
That may give you more clues as to what is happening.

Equivalent to Perl's END block in Ruby

Is there a Perl equivalent END block in Ruby? In Perl, if I specify an END block, the code in that block will get executed no matter where the program bails out. It is great functionality for closing open file handles. Does Ruby support similar functionality? I tried Ruby's "END{}" block but that doesnt seem to get called if I had an exit in the code due to an error.
Thanks!
Use at_exit, which will run regardless of whether an exception was raised or not:
at_exit { puts 'exited!' }
raise
prints "exited" as expected.
You should only consider this if you cannot use an ensure, as at_exit causes logic to reside far away from where the actual exit occurs.
Yes. A block may have an 'ensure' clause. Here's an example:
begin
# This will cause a divide by zero exception
puts 3 / 0
rescue Exception => e
puts "An error occurred: #{e}"
ensure
puts "I get run anyway"
end
Running this produces:
An error occurred: divided by 0
I get run anyway

Run Ruby program until error

Is there a way to make a Ruby program keep executing until the program has an error? I want my loop to stop when the program returns an error.
Thanks
A infinite loop can help?
while true do
your code
end
If your code throw an error the loop stops.
This is another example. Will run infinite times till exception comes and also handles your exception and then exit form code.
inc = 5
while true do
begin
puts 4/inc
inc-=1
rescue Exception=> e
puts e
exit
end
end

Ruby on Linux PTY goes away without EOF, raises Errno::EIO

I'm writing some code which takes a file, passes that file to one of several binaries for processing, and monitors the conversion process for errors. I've written and tested the following routine on OSX but linux fails for reasons about which I'm not clear.
#run the command, capture the output so it doesn't display
PTY.spawn(command) {|r,w,pid|
until r.eof? do
##mark
puts r.readline
end
}
The command that runs varies quite a lot and the code at the ##mark has been simplified into a local echo in an attempt to debug the problem. The command executes and the script prints the expected output in the terminal and then throws an exception.
The error it produces on Debian systems is: Errno::EIO (Input/output error - /dev/pts/0):
All of the command strings I can come up with produce that error, and when I run the code without the local echo block it runs just fine:
PTY.spawn(command) {|r,w,pid|}
In either case the command itself executes fine, but it seems like debian linux isn't sending eof up the pty. The doc pages for PTY, and IO on ruby-doc don't seem to lend any aid here.
Any suggestions? Thanks.
-vox-
So I had to go as far as reading the C source for the PTY library to get really satisfied with what is going on here.
The Ruby PTY doc doesn't really say what the comments in the source code say.
My solution was to put together a wrapper method and to call that from my script where needed. I've also boxed into the method waiting on the process to for sure exit and the accessing of the exit status from $?:
# file: lib/safe_pty.rb
require 'pty'
module SafePty
def self.spawn command, &block
PTY.spawn(command) do |r,w,p|
begin
yield r,w,p
rescue Errno::EIO
ensure
Process.wait p
end
end
$?.exitstatus
end
end
This is used basically the same as PTY.spawn:
require 'safe_pty'
exit_status = SafePty.spawn(command) do |r,w,pid|
until r.eof? do
logger.debug r.readline
end
end
#test exit_status for zeroness
I was more than a little frustrated to find out that this is a valid response, as it was completely undocumented on ruby-doc.
It seems valid for Errno::EIO to be raised here (it simply means the child process has finished and closed the stream), so you should expect that and catch it.
For example, see the selected answer in Continuously read from STDOUT of external process in Ruby and http://www.shanison.com/2010/09/11/ptychildexited-exception-and-ptys-exit-status/
BTW, I did some testing. On Ruby 1.8.7 on Ubuntu 10.04, I don't get a error. With Ruby 1.9.3, I do. With JRuby 1.6.4 on Ubuntu in both 1.8 and 1.9 modes, I don't get an error. On OS X, with 1.8.7, 1.9.2 and 1.9.3, I don't get an error. The behavior is obviously dependent on your Ruby version and platform.
As answered here and here, EIO can be avoided by keeping a file descriptor to the pty slave device open in the parent process.
Since PTY.spawn closes the slave file descriptor passed to the child process, a simple workaround is to open a new one. For example:
PTY.spawn("ls") do |r, w, pid|
r2 = File.open(r.path)
while IO.select([r], [], [], 1)
puts r.gets
end
r2.close
end
ruby-doc.org says this since ruby 1.9:
# The result of read operation when pty slave is closed is platform
# dependent.
ret = begin
m.gets # FreeBSD returns nil.
rescue Errno::EIO # GNU/Linux raises EIO.
nil
end
Ok, so now I get this behavior is "normal" on Linux, but that means it's a little tricky to get the output of a PTY. If you do m.read it reads everything and then throws it away and raises Errno::EIO. You really need to read the content chunk by chunk with m.readline. And even then you risk losing the last line if it doesn't end with "\n" for whatever reason. To be extra safe you need to read the content byte by byte with m.read(1)
Additional note about the effect of tty and pty on buffering: it's not the same as STDOUT.sync = true (unbuffered output) in the child process, but rather it triggers line buffering, where output is flushed on "\n"

Ruby, windows, active_record, and Control-C

What is active_record doing to the signal processes under windows (I don't see this with the same versions on the mac) that causes it to behave so strangely? For instance:
require 'rubygems'
trap("INT"){puts "interrupted"}
puts __LINE__
sleep 5
require 'active_record'
trap("INT"){puts "interrupted again"}
puts __LINE__
sleep 5
When I run the above code (ruby 1.8.6, gem 1.3.1, activerecord 2.2.2,) I can hit ^C as many times as I like during the first sleep, but the first interrupt after the require of activerecord causes the script to terminate. In the above case, the trap still executes, it only fails to allow the program to continue. Usually.
Removing the second call to trap does not have any effect upon the behaviors.
The real annoyance is that in some conditions, the trap fails to execute at all. Considering that the whole point of doing this is to get my code to clean up after itself (remove its footprint in the database so the next guy sees a sane state,) this is a real problem. For instance:
require 'rubygems'
require 'active_record'
trap("INT"){puts "interrupted"}
puts __LINE__
gets
Pressing ^C after seeing the puts will not execute the trap at all.
I only see this problem after requiring active_record. Is there a workaround? I'd be curious to know if this is a bug or if there is an explanation of some sort. As I said, I have no issue with this on the mac - repeated ^Cs result in multiple executions of the trap proc.
thanks...
Considering that the whole point of doing this is to get my code to clean up after itself (remove its footprint in the database ...
Have you considered just using a database transaction? It seems like it would be a much easier way to solve the problem.
I saw a different pattern when trying to duplicate this problem:
puts "start"
trap("INT") { puts "interrupted" }
sleep 5
puts "end"
On Ubuntu (Ruby 1.8.6) this produces
start
interrupted
interrupted
(etc)
interrupted
end
So "interrupted" prints each time Crtl-C is pressed, until the 5 seconds are up. Under Windows (also Ruby 1.8.6), this produces:
start
interrupted
end
i.e. it prints "interrupted" once and then exits.
So it appears that while handling SIGINT Ruby exits the sleep routine and continues on to the next statement. My guess (hand-waving) is that this is somehow due to Ruby using green threads instead of native threads on Windows. Any experts please chime in here.
You could emulate the Unix-y behavior by restarting sleep in the handler:
puts "start"
trap("INT") do
puts "interrupted"
sleep 5
end
sleep 5
puts "end"
Unfortunately this resets the timer each time SIGINT is trapped, so it needs some hacking:
$interval = 5
def go_to_sleep(secs)
$started = Time.now
sleep secs
end
trap("INT") do
puts "interrupted"
time_to_sleep = [0,$interval - (Time.now - $started)].max
if time_to_sleep > 0
sleep time_to_sleep
end
end
puts "one"
go_to_sleep($interval)
puts "two"
go_to_sleep($interval)
puts "three"
go_to_sleep($interval)

Resources