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)}
----------------------------------------------------------------