Dynamic Method Call within define_method
I'm rather new to ruby, but am in a sit开发者_如何学编程uation where I have many repetitive methods. In attempting to DRY out my code I came up with something like the following:
class Foobar
def some_method
#
end
def some_method2
#
end
def some_calculation
#
end
[:some_method_test, :some_method2_test].each do |method|
define_method method do
return self.send(method.to_s.chomp "_test") / some_calculation
end
end
end
My question is regarding the .to_s.comp-- is there another way of writing this and accomplishing my goal?
Yes, you could start with the original name.
[:some_method, :some_method2].each do |method|
define_method :"#{method}_test" do
return self.send(method) / some_calculation
end
end
Note that this kind of metaprogramming usually doesn't make much sense unless you have a very large number of trivial methods.
You could try to reduce the number of trivial methods. Maybe you could replace some_method
, some_method2
, some_method3
with generic_method(attribute_desired)
where you'd call generic_method(1)
instead of some_method
, call generic_method(2)
instead of some_method2
, etc.
Sometimes testing can tell you something about the code that's being tested. If the testing is very boring, maybe it means the code being tested is too boring and has too much duplication.
And here is still another solution:
class Foobar
# Non-test method definitions ...
%w(some_method some_method2).each do |mthd|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def #{mthd}_test
#{mthd} / some_calculation
end
EOS
end
end
In this way, the method definitions themselves are a bit slower, but they run much faster because they call no reflection method like send
, and there stacktraces are shallower.
BTW, %w(foo bar)
stands for words, and produces ['foo', 'bar']
.
<<-EOS
blah blah
blah blah
EOS
is just a string that spreads multiple lines(HERE doc).
class_eval
evaluates the string as a script, in the context of the current class(class Foobar
). The __FILE__
and __LINE__ + 1
affect the file path and line number in the stacktrace.
精彩评论