define_method in ruby
So one more step close to meta programming define_method.
The usual way of defining new methods is to put your intended logic between
But consider a situation where you have to create a series of methods all of which have the same basic structure save for one string, and which can only be one of a certain set of strings. Now, you might say we'll just define one method and accept that one string as a parameter, which we can then use wherever we want. And you'd be right. But, the problem with such an approach is it's not particularly declarative: you don't know exactly what values that optional parameter can accept.
Isn't that nice? We have code that's generating the code for us. Pretty meta, isn't it?
In fact, we can now extend this by adding any number of elements to that array -- or replacing the array entirely with an external data source. Many Ruby libraries use exactly this technique to define methods dynamically based on, say, database schemas. Rails, for example, will create methods such as
The usual way of defining new methods is to put your intended logic between
def
& end
. And that works perfectly fine for the most part.But consider a situation where you have to create a series of methods all of which have the same basic structure save for one string, and which can only be one of a certain set of strings. Now, you might say we'll just define one method and accept that one string as a parameter, which we can then use wherever we want. And you'd be right. But, the problem with such an approach is it's not particularly declarative: you don't know exactly what values that optional parameter can accept.
class DefineMethodThe real power of
define_method("perform_chunk") do |argument|
"performing chunk on #{argument}"
end
define_method("perform_chomp") do |argument|
"performing chomp on #{argument}"
end
end
d= DefineMethod.new
puts d.perform_chunk("nose")
puts d.perform_chomp("string")
define_method
is realised when we realise
we call it like any other code. Here's an example where we call it
inside a loop and it achieves the same result as above. class Doctor
["assoc", "rassoc", "reduce"].each do |action|
define_method("perform_#{action}") do |argument|
"performing #{action.gsub('_', ' ')} on #{argument}"
end
end
end
doctor = Doctor.new
puts doctor.perform_assoc("nose")
puts doctor.perform_rassoc("throat")
puts doctor.perform_reduce("in da club")
Isn't that nice? We have code that's generating the code for us. Pretty meta, isn't it?
In fact, we can now extend this by adding any number of elements to that array -- or replacing the array entirely with an external data source. Many Ruby libraries use exactly this technique to define methods dynamically based on, say, database schemas. Rails, for example, will create methods such as
Customer#find_by_first_name_and_last_name
Comments
Post a Comment