class_eval выпуск Ruby - PullRequest
       11

class_eval выпуск Ruby

0 голосов
/ 14 ноября 2011

Я пытаюсь использовать class_eval для создания метапрограммного метода, если вызываемый метод начинается с «плюс». Однако у меня возникли проблемы при составлении фактического синтаксиса class_eval

class Adder
  def initialize(my_num)
    @my_num = my_num
  end
  def my_num
    @my_num
  end
end
    def method_missing(meth, *args)
        my_meth = meth.to_s
        #puts my_meth[0, 4]
        if my_meth[0, 4] == "plus" then #/plus\d/ then
            num = my_meth.slice(/\d+/).to_i

            original_num = self.my_num.to_i
            my_sum = original_num + num
            class_eval{ eval{"def #{meth}; @my_int = #{my_sum} return @my_int end\n"}}
        end
        else
        super
    end


y = Adder.new(12)
puts y.plus10

Когда вызывается плюс10 (или любой другой номер), вновь созданный метод должен добавить это число к целому числу, которое вызывается, и произвести новую сумму.

Спасибо

1 Ответ

1 голос
/ 14 ноября 2011

Попробуйте это:

class Adder
  def initialize(my_num)
    @my_num = my_num
  end
  def my_num
    @my_num
  end
  def method_missing(meth, *args)
    my_meth = meth.to_s
      if my_meth[0, 4] == "plus" then
        num = my_meth.slice(/\d+/).to_i
        original_num = my_num
        my_sum = original_num + num
        self.class.class_eval do
          define_method "#{meth}" do
            my_int = my_sum
          end
        end
        send meth
      else
        super
      end
  end
end
y = Adder.new(12)
puts y.plus10  # => 22

UPDATE

и это слегка улучшенная версия:

class Adder
  def initialize(num)
    @num = num
  end

  def method_missing(name, *args)
    name_string = name.to_s
    if /^plus(\d+)/ =~ name_string
      sum = Regexp.last_match(1).to_i + @num
      self.class.class_eval do
        define_method "#{name}" do
          sum
        end
      end
      send name
    else
     super
    end
  end
end

y = Adder.new(12)
puts y.plus10  # => 22
...