I'm doing some (too) fancy meta programming, and I have a hard time understanding why the scope is different in the following two cases:
Case 1:
class TesterA
def the_method
puts "I'm an instance_method!"
end
def self.the_method
puts "I'm a class_method!"
end
def self.define_my_methods *method_names
method_names.each do |name|
define_method("method_#{name}") do
the_method
end
end
end
define_my_methods :a, :b, :c
end
t = TesterA.new
t.method_a #=> I'm an instance_method!
t.method_b #=> I'm an instance_method!
t.method_c #=> I'm an instance_method!
Case 2
class TesterB
def the_method
puts "I'm an instance_method!"
end
def self.the_method
puts "I'm a class_method!"
end
def self.define_the_method attr
define_method("method_#{attr}") do
begin
yield
rescue
raise $!, "method_#{attr} was called: #$!", $@
end
end
end
def self.define_my_methods *method_names
method_names.each do |name|
define_the_method(name) do
the_method
end
end
end
define_my_methods :a, :b, :c
end
t = TesterB.new
t.method_a #=> I'm a class_method!
t.method_b #=> I'm a class_method!
t.method_c #=> I'm a class_method!
I the second example I introduce a kind of "helper-mothod" define_the_method
which I use for defining the methods rather than define_method
it self. Reason for that is, That I want to append the name of the dynamic method to any exception messages that might occur inside those methods. The problem however is, that the content (when using the latter case) seems to be evaluated in the class-scope.
Why is this, and how can I make it get evaluated in the instance-scope?