代码之家  ›  专栏  ›  技术社区  ›  Larry K

Rails元编程:如何在运行时添加实例方法?

  •  4
  • Larry K  · 技术社区  · 16 年前

    添加方法的启动代码应该从哪里调用?

    class Info < ActiveRecord::Base
    
    end
    
    # called from an init file to add the instance methods
    parts = []
    (0..9).each do |i|
       parts.push "def user_field_#{i}"     # def user_field_0
       parts.push   "get_user_fields && @user_fields[#{i}]"
       parts.push "end"
    end
    
    Info.class_eval parts.join
    
    2 回复  |  直到 16 年前
        1
  •  11
  •   Marc-André Lafortune    16 年前

    一个很好的方法是使用 method_missing :

    class Info
      USER_FIELD_METHOD = /^user_field_(\n+)$/
      def method_missing(method, *arg)
        return super unless method =~ USER_FIELD_METHOD
        i = Regexp.last_match[1].to_i
        get_user_fields && @user_fields[i]
      end
    
      # Useful in 1.9.2, or with backports gem:
      def respond_to_missing?(method, private)  
        super || method =~ USER_FIELD_METHOD
      end
    end        
    

    如果您喜欢定义方法:

    10.times do |i|
      Info.class_eval do
        define_method :"user_field_#{i}" do
          get_user_fields && @user_fields[i]
        end
      end
    end
    
        2
  •  4
  •   Andrew Grimm Alex Wayne    15 年前

    method_missing 很难维护,也没有必要。另一种选择是使用 define_method

    class Info
    end
    
    Info.class_eval 10.times.inject("") {|s,i| s += <<END}
      def user_field_#{i}
        puts "in user_field_#{i}"
      end
    END
    
    puts Info.new.user_field_4