Dynamically add methods in ruby with define_method
In a recent post I went over adding methods dynamically with method_missing. I also issued a word of caution when overriding method_missing
in that manor.
It turns out there is a better way to handle an event where you need to define methods at runtime in ruby, through the use of define_method
. The benefit to using define_method
in this case is it will have any unintended side effects like method_missing
does with impacting respond_to?.
In the code below I use define_method
to add attribute methods to the Account
class. When this file is first read by the ruby interpreter it will iterate the @@attributes
array and create the setter methods. Then we can use them later on in our code, like where the example below illustrates when we set a value for email.
class Account
@@attributes = [:email, :first_name, :last_name]
@@attributes.each do |name|
define_method(:"#{name}=") do |value|
@attributes[name] = value
end
end
def initialize
@attributes = {}
end
end
Account.new.email = "wizbang@buck.com"
If it’s not clear, what makes this dynamic is our code is defining the attribute methods for us inside of define_method
as it runs rather than us declaring them within our code.
I’ve seen this used in production where a remote API contains data you want to attach to a class in a different ruby/rails app. The data is fetched from the API and define_method
is used to attach that data to the model.