Ruby" method_missing"创建后运行方法

时间:2018-01-27 22:37:28

标签: ruby method-missing

我试图在method_missing的帮助下尝试实现一个代码,如果它适合某个关键字,则自动创建一个方法。

到目前为止这是有效的:

class Add
    def initialize()
        @result = ""
    end


    def output()
        puts @result
     end

    def method_missing(name, *args)
        if name.to_s.include? "add"
            code = "def #{name}(*args)"\
            "@result << args.to_s;"\
            "end"
            instance_eval(code)
        end
    end
end

 a = Add.new

 a.add_1("1") #created but not called
 a.add_2("2") #created but not called
 a.add_2("2") #called
 a.output #I want it to return 122, but it returns only 2 once.

我希望方法在创建后运行。这种情况不会发生,因为必须在执行代码之前再次调用该方法。

我该如何实现?

3 个答案:

答案 0 :(得分:1)

作为一个起点,也许是这样的。

class Add
  def initialize
    @result = ""
  end

  def output
    @result
  end

  def method_missing(name,arg)
    if name.to_s.include? 'add'
      @result << arg
      arg
    else
      super
    end
  end
end

a = Add.new

p a.add '1'  # "1"
p a.add '2'  # "2"
p a.add '2'  # "2"
p a.output   # "122"

p a.minus '1' #NoMethodError

答案 1 :(得分:1)

以下代码应达到您的目的:

class Add
  def initialize
    @result = ""
  end

  def output
    @result
  end

  def method_missing(name, *args, &block)
    if name.to_s.include?("add")
      self.class.send(:define_method, name) do |args|
        @result << args.to_s
      end

      self.send(name, *args)
    end
  end
end

但是,在method_missing范围内,您只需执行

即可
def method_missing(name, *args, &block)
  if name.include? "add"
    @result << args.join(" ")
  end
end

这应该仍然有用

答案 2 :(得分:1)

class Add

    def initialize
        @result = ''
    end

    def output
      puts @result
    end

    def method_missing(name, *args)
        if name =~ /add/
          Add.instance_eval do
            define_method(name) do |args|
              @result << args[0]
            end
          end
          send(name, args)
        else
          super
        end
    end
end