nicosuria nicosuria - 1 month ago 10
Ruby Question

Dynamically defined setter methods using define_method?

I use a lot of iterations to define convenience methods in my models, stuff like:

PET_NAMES.each do |pn|
define_method(pn) do
...
...
end


but I've never been able to dynamically define setter methods, ie:

def pet_name=(name)
...
end


using define_method like so:

define_method("pet_name=(name)") do
...
end


Any ideas? Thanks in advance.

Answer

Here's a fairly full example of using define_method in a module that you use to extend your class:

module VerboseSetter
  def make_verbose_setter(*names)
    names.each do |name|
      define_method("#{name}=") do |val|
        puts "@#{name} was set to #{val}"
        instance_variable_set("@#{name}", val)
      end
    end
  end
end

class Foo
  extend VerboseSetter

  make_verbose_setter :bar, :quux
end

f = Foo.new
f.bar = 5
f.quux = 10

Output:

@bar was set to 5
@quux was set to 10

You were close, but you don't want to include the argument of the method inside the arguments of your call to define_method. The arguments go in the block you pass to define_method.