Dynamically defined setter methods using define_method?

后端 未结 2 449
南笙
南笙 2021-02-04 05:52

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

相关标签:
2条回答
  • 2021-02-04 06:52

    Shoertly if you need it inside one class/module: I use hash but you can put there array of elements etc.

    PETS = {
      "cat" => "meyow",
      "cow" => "moo",
      "dog" => "ruff"
    }
    
    def do_smth1(v)
    ...
    end
    
    def do_smth(sound,v)
    ...
    end
    
    #getter
    PETS.each{ |k,v| define_method(k){ do_smth1(v) } }
    
    #setter
    PETS.each{ |k,v| define_method("#{k}="){|sound| do_smth2(sound, v) }
    
    0 讨论(0)
  • 2021-02-04 06:54

    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.

    0 讨论(0)
提交回复
热议问题