define_method: 如何动态创建带参数的方法
define_method: How to dynamically create methods with arguments
我想为 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
有什么想法吗?提前致谢。
如果你阅读这里的例子http://apidock.com/ruby/Module/define_method你会发现这个:
define_method(:my_method) do |foo, bar| # or even |*args|
# do something
end
与
相同
def my_method(foo, bar)
# do something
end
如果我没有正确理解你的问题,你想要这样的东西:
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
(我假设 all
方法 returns 是一个 Enumerable。)
以上或多或少等同于定义两个 class 方法,如下所示:
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
当你这样做时:define_method("self.find_by_#{attribute}")
这是不正确的。 define_method 的参数是一个带有单个单词的符号。
让我给你看一些正确的代码,希望这会很清楚:
class MyClass < ActiveRecord::Base
["name", "brand"].each do |attribute|
define_method(:"find_by_#{attribute}") do |attr_|
first(attribute.to_sym => attr_)
end
end
end
这将为 find_by_brand
和 find_by_name
生成 class 方法。
请注意,如果您正在研究元编程,这是 method_missing 的一个很好的用例。 here's a tutorial 使用 method_missing 实现您想要的相同功能 (find_by_<x>
)
我想为 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
有什么想法吗?提前致谢。
如果你阅读这里的例子http://apidock.com/ruby/Module/define_method你会发现这个:
define_method(:my_method) do |foo, bar| # or even |*args|
# do something
end
与
相同def my_method(foo, bar)
# do something
end
如果我没有正确理解你的问题,你想要这样的东西:
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
(我假设 all
方法 returns 是一个 Enumerable。)
以上或多或少等同于定义两个 class 方法,如下所示:
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
当你这样做时:define_method("self.find_by_#{attribute}")
这是不正确的。 define_method 的参数是一个带有单个单词的符号。
让我给你看一些正确的代码,希望这会很清楚:
class MyClass < ActiveRecord::Base
["name", "brand"].each do |attribute|
define_method(:"find_by_#{attribute}") do |attr_|
first(attribute.to_sym => attr_)
end
end
end
这将为 find_by_brand
和 find_by_name
生成 class 方法。
请注意,如果您正在研究元编程,这是 method_missing 的一个很好的用例。 here's a tutorial 使用 method_missing 实现您想要的相同功能 (find_by_<x>
)