{Code block} Ruby Gtk

Hi everyone, I am very new to Ruby. A few days earlier I was looking at
a ruby-gtk tutorial by Zetcode.com
(http://zetcode.com/gui/rubygtk/introduction/) which in one of the
examples provided contains the following lines that I have trouble to
understand

    signal_connect "destroy" do
        Gtk.main_quit
    end

Why it is necessary to use a block at this particular circumstance? In
python, this can be declared directly as:

    self.connect("destroy", gtk.main_quit)

The following is the original example.

class RubyApp < Gtk::Window

def initialize
    super
    set_title "Center"
    signal_connect "destroy" do
        Gtk.main_quit
    end
    set_default_size 300, 200
    set_window_position Gtk::Window::Position::CENTER
    show
end

end

This is the Python equivalent:

class PyApp(gtk.Window):
def init(self):
super(PyApp, self).init()

    self.connect("destroy", gtk.main_quit)
    self.set_size_request(300, 200)
    self.set_position(gtk.WIN_POS_CENTER)
    self.show()

Thank you very much

Sincerely
Lawrence

What you need to do is to pass a function that gets called when the
signal is emitted. Often, you may need a custom function, which is done
by passing a custom block do signal_connect that does the work.

If all you need is to call some pre-defined function, you might think it
would be enough to pass that function’s name. If you really want, you
can do this in ruby as well.

The first idea might be

signal_connect :destroy, &Gtk.method(:main_quit)

This will not work, as the block upon callback receives the Gtk::Window
/ Application as an argument, but Gtk.main_quit does not take any
arguments.

Gtk.method(:main_quit).arity
=> 0

So you will to define as wrapper function:

main_quit = ->*args{Gtk.main_quit}

And now you can simply pass the function instead of creating a new
block:

signal_connect :destroy, &main_quit

Note that you can’t simply write

signal_connect :destroy, Gtk.main_quit

or

signal_connect :destroy, main_quit

as Gtk.main_quit, even without without parentheses () and contrary to
python, would actually call the function and pass its return value. ()
are optional for function/method calls in ruby.

ruby:

def test
end
puts 9
puts method(:test)
exit
puts 10

python:

def test():
0
print 9
print test
exit()
print 10

And instead of defining a wrapper function, you might as well pass it
directly as a block:

signal_connect(:destroy){ Gtk.main_quit }

or

signal_connect :destroy do
Gtk.main_quit
end

Thank you very much for your detailed explanation Dansei!