将动态方法添加到class.methods数组中

时间:2011-12-21 07:28:23

标签: ruby

我正在使用 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

有没有办法可以做到这一点?

提前致谢。

1 个答案:

答案 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方法。

我不完全确定你要在这里完成什么,但正如彼得在评论中所说,你可能需要重构你的代码,因为这看起来不太干净。