From: Brian Candler Date: 2008-10-23T18:55:41+09:00 Subject: Re: Is there a method_eval or similar thing ? Nit Khair wrote: > askyn("Do you wish to proceed?", 'n') do > actionbind(:yes) { puts "user pressed yes" } > actionbind(:no) { puts "user pressed no" } > end As you have already realised, you need somewhere to store the bindings between keys and actions. This could be a hash allocated by askyn: askyn("Do you wish to proceed?", "n") do |h| actionbind(h,:yes) { puts "user pressed yes" } ... etc But in this case I think a wrapper object to hold the bindings would be better, as already posted by someone else. (That's what the optparse.rb library does, amongst others; it's a clean and well-recognised solution) However you could turn it around and get the caller to pass a pre-prepared hash containing all the bindings to askyn: askyn("Do you wish to proceed?", "n", :yes => lambda { puts "user pressed yes" } :no => lambda { puts "user pressed no" } ) I quite like that approach. This sort of API also makes it easy for the user to invoke other methods in their object for each response, e.g. askyn("Do you wish to proceed?", "n" :yes => method(:do_yes), :no => method(:do_no) ) Now, as you say, you could keep your hash in a global variable, but that would be very poor as it would make your code non-threadsafe. But it's possible to fix this by using a thread-local variable: def askyn(prompt, default) Thread[:askyn] = {} yield .. etc end def actionbind(key, &block) Thread[:askyn][key] = block end I'd say that smells somewhat, but it would work and it hides the hash. Or scarily, you could attempt to create a local variable in the binding of the caller, which is I think what you were asking for initially. This is pretty horrible and I won't even attempt it here :-) You can google for binding_of_caller, and note that eval lets you pass in a binding. Regards, Brian. P.S. Note that if you nest def within a def, as your posted code does, it probably doesn't do what you expect. The inner def will define a new method in your object, at the time when the outer def is called. -- Posted via http://www.ruby-forum.com/.