Динамический вызов метода в define_method - PullRequest
1 голос
/ 04 октября 2011

Я довольно плохо знаком с ruby, но нахожусь в ситуации, когда у меня много повторяющихся методов.В попытке высушить мой код я придумал что-то вроде следующего:

class Foobar
  def some_method
    #
  end

  def some_method2
    #
  end

  def some_calculation
    #
  end

  [:some_method_test, :some_method2_test].each do |method|
    define_method method do
      return self.send(method.to_s.chomp "_test") / some_calculation
    end
  end
end

Мой вопрос касается .to_s.comp - есть ли другой способ написать это и выполнить мою цель?*

Ответы [ 3 ]

2 голосов
/ 05 октября 2011

Вы можете попытаться сократить количество тривиальных методов. Возможно, вы могли бы заменить some_method, some_method2, some_method3 на generic_method(attribute_desired), где вы бы позвонили generic_method(1) вместо some_method, позвоните generic_method(2) вместо some_method2 и т. Д.

Иногда тестирование может рассказать вам кое-что о тестируемом коде. Если тестирование очень скучное, возможно, это означает, что тестируемый код слишком скучен и имеет слишком много дублирования.

2 голосов
/ 05 октября 2011

Да, вы можете начать с оригинального имени.

[:some_method, :some_method2].each do |method|
  define_method :"#{method}_test" do
    return self.send(method) / some_calculation
  end
end

Обратите внимание, что этот вид метапрограммирования обычно не имеет большого смысла, если у вас нет очень большого числа тривиальных методов.

1 голос
/ 05 февраля 2015

А вот еще одно решение:

class Foobar
  # Non-test method definitions ...

  %w(some_method some_method2).each do |mthd|
    class_eval(<<-EOS, __FILE__, __LINE__ + 1)
      def #{mthd}_test
        #{mthd} / some_calculation
      end
    EOS
  end
end

Таким образом, сами определения методов немного медленнее, но они работают намного быстрее, потому что они не вызывают никакого метода отражения, такого как send, и там следы стека меньше.

Кстати, %w(foo bar) означает слова и производит ['foo', 'bar'].

<<-EOS
  blah blah
  blah blah
EOS

- это просто строка, которая состоит из нескольких строк (ЗДЕСЬ документ).

class_eval оценивает строку как скрипт в контексте текущего класса (класс Foobar). __FILE__ и __LINE__ + 1 влияют на путь к файлу и номер строки в трассировке стека.

...