method_missing question

J

Joe Van Dyk

Currently, I have a class that has a bunch of methods (that a GUI does
a callback on) that are like

def menu_zoom_100_activate
@display.zoom(100)
end

def menu_zoom_250_activate
@display.zoom(250)
end

def menu_zoom_500_activate
@display.zoom(500)
end

Could I use #method_missing to make this better?
 
R

Rick Olson

Why not just call @display.zoom(500)?

Currently, I have a class that has a bunch of methods (that a GUI does
a callback on) that are like

def menu_zoom_100_activate
@display.zoom(100)
end

def menu_zoom_250_activate
@display.zoom(250)
end

def menu_zoom_500_activate
@display.zoom(500)
end

Could I use #method_missing to make this better?
 
J

Joe Van Dyk

Why not just call @display.zoom(500)?

Because when a GUI button is clicked, I need to call a particular
method of a particular class. I don't think I can give it an
argument.
 
J

Joe Van Dyk

Because when a GUI button is clicked, I need to call a particular
method of a particular class. I don't think I can give it an
argument.

Actually, (I'm using Glade) I have this:

app_window = AppWindow.new
GladeXML.new("app.glade") { |handler| app_window.method(handler) }

Where AppWindow is a class that contains all the methods that are
defined in the glade file. In the glade file are methods being
registered like "menu_zoom_250_activate", "menu_zoom_500_activate" and
so on.

If a particular method that's contained in the glade file isn't
defined in the AppWindow class, I get a "undefined method '<some
method>' for class AppWindow" upon the start of the application.

I added AppWindow#method_missing that just prints out the missing
method, but that didn't seem to solve anything.

Perhaps it would be best to have a single method in AppWindow that
took all the methods (as a string) that were defined in the glade file
and executed the appropriate action?

So,

GladeXML.new("app.glade") { |handler| app_window.execute_method(handler) }

class AppWindow
def execute_method(method)
case method
when /menu_zoom_(\d+)_activate/
@display.zoom($1.to_i)
when "something_else"
# do something else
end
end
end
 
J

Joe Van Dyk

Actually, (I'm using Glade) I have this:

app_window = AppWindow.new
GladeXML.new("app.glade") { |handler| app_window.method(handler) }

Where AppWindow is a class that contains all the methods that are
defined in the glade file. In the glade file are methods being
registered like "menu_zoom_250_activate", "menu_zoom_500_activate" and
so on.

If a particular method that's contained in the glade file isn't
defined in the AppWindow class, I get a "undefined method '<some
method>' for class AppWindow" upon the start of the application.

I added AppWindow#method_missing that just prints out the missing
method, but that didn't seem to solve anything.

Perhaps it would be best to have a single method in AppWindow that
took all the methods (as a string) that were defined in the glade file
and executed the appropriate action?

So,

GladeXML.new("app.glade") { |handler| app_window.execute_method(handler) }

class AppWindow
def execute_method(method)
case method
when /menu_zoom_(\d+)_activate/
@display.zoom($1.to_i)
when "something_else"
# do something else
end
end
end

Nuts, I tried that, and AppWindow#execute_method is being run at
application start for each method defined in the glade file, and now
none of the GUI events do anything. Hm.
 
C

Curt Hibbs

Joe said:
Nuts, I tried that, and AppWindow#execute_method is being run at
application start for each method defined in the glade file, and now
none of the GUI events do anything. Hm.

How about going back to you method_missing idea, and then in
method_missing, parsing the name of the method that was being called and
converting that to a method call that you eval.

For example: if the method being called was "display_zoom_250", convert
that to the string "@display.zoom(250)" and then eval that string.

Curt
 
P

Pit Capitain

Joe said:
Currently, I have a class that has a bunch of methods (that a GUI does
a callback on) that are like

def menu_zoom_100_activate
@display.zoom(100)
end

def menu_zoom_250_activate
@display.zoom(250)
end

def menu_zoom_500_activate
@display.zoom(500)
end

Could I use #method_missing to make this better?

You should be able to use method_missing, but you could also do
something like

class Handler

[ 100, 250, 500 ].each do |factor|
define_method("menu_zoom_#{factor}_activate") do
@display.zoom(factor)
end
end

end

or for some more syntax sugar define a class method

class Handler

class << self
def zoom_methods(*factors)
...see above...
end
end

zoom_methods 100, 250, 500

end

Regards,
Pit
 
H

Henon

Joe said:
Currently, I have a class that has a bunch of methods (that a GUI does
a callback on) that are like

def menu_zoom_100_activate
@display.zoom(100)
end

def menu_zoom_250_activate
@display.zoom(250)
end

def menu_zoom_500_activate
@display.zoom(500)
end

Could I use #method_missing to make this better?

you could do that like this:

def method_missing(methodname, *args)
if methodname=~/menu_zoom(\d+)_activate/
@display.zoom($1.to_i)
else
super
end
end
 
J

Joe Van Dyk

Joe said:
Currently, I have a class that has a bunch of methods (that a GUI does
a callback on) that are like

def menu_zoom_100_activate
@display.zoom(100)
end

def menu_zoom_250_activate
@display.zoom(250)
end

def menu_zoom_500_activate
@display.zoom(500)
end

Could I use #method_missing to make this better?

You should be able to use method_missing, but you could also do
something like

class Handler

[ 100, 250, 500 ].each do |factor|
define_method("menu_zoom_#{factor}_activate") do
@display.zoom(factor)
end
end

end

DING DING DING.

The above worked perfectly. Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top