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
Related
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.
below is the code which is called by the gtk closing action -->
def on_main_window_destroy(object)
begin
$client.send(':exit')
Thread.kill $client.response
rescue
puts 'exiting'
end
Thread.kill $receiving_message
Gtk.main_quit()
exit
end
which results in this output.
app.rb:81:in `exit': exit
from app.rb:81:in `on_main_window_destroy'
from /home/user/.gem/ruby/2.4.0/gems/gobject-introspection-3.1.8/lib/gobject-introspection/loader.rb:110:in `invoke'
from /home/user/.gem/ruby/2.4.0/gems/gobject-introspection-3.1.8/lib/gobject-introspection/loader.rb:110:in `block in define_singleton_method'
from app.rb:97:in `<main>'
the program works fine .. and it doesn't create a mess for me .. but i want to know the reasons for these errors so that i can handle it.
The Kernel#exit raises an exception to terminate the program, that looks like be the exception message you're asking about:
Initiates the termination of the Ruby script by raising the SystemExit exception. This exception may be caught.
As for the "block in define_singleton_method" part of the stack trace, while ruby has a define_singleton_method, if you look at line 110 of that file specified, you'll see that the method you are in is also called define_singleton_method and you are inside a block in that method:
def define_singleton_method(klass, name, info)
# ...
singleton_class.__send__(:define_method, name) do |*arguments, &block|
arguments, block = prepare.call(arguments, &block) # <<< Line 110
# ...
end
end
I'm not sure why you're actually seeing that output instead of just exiting silently like you normally would, a possibility is that somewhere in the code, something is just rescuing the base Exception, instead of StandardError, which is generally a bad idea, though they may be just logging/outputting and re-raising it (which as seen in some of those answers, is OK), it's all just speculation without digging around a lot further into the code (it might not even be in this gem)
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
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
Is there a one line function call that quits the program and displays a message? I know in Perl it's as simple as:
die("Message goes here")
I'm tired of typing this:
puts "Message goes here"
exit
The abort function does this. For example:
abort("Message goes here")
Note: the abort message will be written to STDERR as opposed to puts which will write to STDOUT.
If you want to denote an actual error in your code, you could raise a RuntimeError exception:
raise RuntimeError, 'Message goes here'
This will print a stacktrace, the type of the exception being raised and the message that you provided. Depending on your users, a stacktrace might be too scary, and the actual message might get lost in the noise. On the other hand, if you die because of an actual error, a stacktrace will give you additional information for debugging.
I got here searching for a way to execute some code whenever the program ends.
Found this:
Kernel.at_exit { puts "sayonara" }
# do whatever
# [...]
# call #exit or #abort or just let the program end
# calling #exit! will skip the call
Called multiple times will register multiple handlers.
I've never heard of such a function, but it would be trivial enough to implement...
def die(msg)
puts msg
exit
end
Then, if this is defined in some .rb file that you include in all your scripts, you are golden.... just because it's not built in doesn't mean you can't do it yourself ;-)