define_method:如何使用参数动态创建方法

Kos*_*nos 31 ruby metaprogramming

我想为find_by功能创建一堆方法.我不想一遍又一遍地写同样的东西所以我想使用元编程.

假设我想创建一个按名称查找的方法,接受名称作为参数.我该怎么办?我以前使用过define_method但是我没有任何关于该方法的参数.这是我的(坏)方法

["name", "brand"].each do |attribute|
    define_method("self.find_by_#{attribute}") do |attr_|
      all.each do |prod|
        return prod if prod.attr_ == attr_
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?提前致谢.

Jor*_*ing 42

如果我正确理解你的问题,你想要这样的东西:

class Product
  class << self
    [:name, :brand].each do |attribute|
      define_method :"find_by_#{attribute}" do |value|
        all.find {|prod| prod.public_send(attribute) == value }
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

(我假设该all方法返回一个Enumerable.)

以上或多或少等同于定义两个类方法,如下所示:

class Product
  def self.find_by_name(value)
    all.find {|prod| prod.name == value }
  end

  def self.find_by_brand(value)
    all.find {|prod| prod.brand == value }
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 更惯用的方法是使用`define_singleton_method`. (2认同)

Alb*_*bin 5

如果您在http://apidock.com/ruby/Module/define_method上阅读示例,则会发现它:

define_method(:my_method) do |foo, bar| # or even |*args|
  # do something
end
Run Code Online (Sandbox Code Playgroud)

是相同的

def my_method(foo, bar)
   # do something
end
Run Code Online (Sandbox Code Playgroud)