From: Erik Veenstra Date: 2006-12-13T08:26:05+09:00 Subject: Re: How do I catch a missing method on a passed block? I've some comments, on almost all code in this thread. Feel free to ignore me... All code is "polluted" with meta-code stuff and "class << object" stuff and "instance_eval" stuff and "class_eval" stuff and other stuff. That doesn't feel good. Well, you need this code to do the trick, but... It's usually a good idea to separate business logic and low level code. The novice programmers and mediocre programmers can concentrate on the business level code, while the more seasoned programmer can write the low-level code. The novice programmer is the user of the code made by the smart guy. The novice programmer only sees clean code: He understands what he is doing and is happy. Smart Guy is the, well, uh, smart guy and is happy too. Everybody's happy! I've mixed business code and low-level code myself, in the past. After one month, I simply couldn't read my own code, solely because I was mixing both levels. So, even if you are a smart guy and the only developer, it's still a good idea to think and code on different levels. I've rewritten one of the examples. Lines 1-12 are (is?) low-level code (generic) and can and should be hidden in a library. Lines 14-28 are (is?) the business code (non-generic). On line 16, we wrap the received block, which could easily be commented out, if necessary. Method_missing_inspect calls block_with_method_missing with the given block and a (non-generic) method_missing block. Block_with_method_missing enriches the given block1 with a method_missing (which is implemented by block2) and returns the enriched block1. The result is that Foo#bar, the business logic, is still very clean and very readable. Method_missing_inspect is a bit more sophisticated, but still understandable for Joe Average. Block_with_method_missing is the work of Smart A^HGuy... Just my thoughts. Ignore me, if appropriate... gegroet, Erik V. - http://www.erikveen.dds.nl/ ---------------------------------------------------------------- 1 module Kernel 2 def block_with_method_missing(block1, &block2) 3 class << block1 4 self 5 end.module_eval do 6 define_method(:method_missing, &block2) 7 define_method(:call){block1.instance_eval(&block1)} 8 end 9 10 block1 11 end 12 end 13 14 class Foo 15 def bar(&block) 16 block = method_missing_inspect(block) 17 18 block.call 19 end 20 21 def method_missing_inspect(block) 22 block_with_method_missing(block) do |method_name, *args| 23 p [:mm, method_name, args] 24 end 25 end 26 end 27 28 Foo.new.bar{baz(1, 2, 3)} ----------------------------------------------------------------