我正在使用 method_missing 函数创建动态方法。 它的工作正常,但我想做的是,将这些方法添加到 ClassName.methods 数组。代码如下:
module MyObjectStore
values = []
temp = {}
def self.included(kls)
kls.extend ClassMethods
end
ClassMethods = Module.new do
define_method :method_missing do |method,*args,&block|
if method =~ /find_by_/
methods << method
add_search_method(method,*args)
else
values.send "#{method}", &block
end
end
define_method :add_search_method do |method,*args|
values.each do |obj|
x = obj.send "#{method.to_s.split('_')[-1]}"
if x == args[0]
p obj
end
end
end
end
define_method :add_check_attribute do |method,*args|
if method.to_s =~ /=$/
temp[method[0..-2]] = args[0]
else
instance_variable_get("@#{method}")
end
end
define_method :method_missing do |method,*args|
add_check_attribute(method,*args)
end
define_method :save do
temp.each {|key,value| instance_variable_set("@#{key}",value)}
values << self
end
end
class C
include MyObjectStore
end
我正在将新方法添加到方法Array中。它在这里添加得很好。问题是,当我引用C类,并尝试找到新添加的方法时,它什么都不返回。即。
a = C.new
a.id = 1
a.name = 'gaurav'
a.save
C.find_by_name('gaurav')
p a.methods.include?(:find_by_name)
返回 false
有没有办法可以做到这一点?
提前致谢。
答案 0 :(得分:0)
这里,新方法是为C类定义的类方法。 但是&#39; a&#39;是C的一个实例,所以你不会看到这些方法。
这将返回true
p a.class.methods.include?(:find_by_name)
EDITED
您假设methods << method
会将方法添加到模块中,但它不会执行此类操作。所以你需要明确定义这样的方法,
ClassMethods = Module.new do
def method_missing(method, *args, &block)
if method =~ /find_by_/
add_search_method(method,*args)
send(method, *args)
else
values.send "#{method}", &block
end
end
def add_search_method(method, *args)
define_singleton_method(method) do |*args|
@@values.each do |obj|
return obj if obj.send("#{method.to_s.split('_')[-1]}") == args[0]
end
nil
end
end
end
用这个替换你的ClassMethods定义,C.methods将包括你的find by方法。
我不完全确定你要在这里完成什么,但正如彼得在评论中所说,你可能需要重构你的代码,因为这看起来不太干净。