рубиновый вопрос о перегрузке оператора

Я просто хотел выделить это статья, что @Jeff ссылки Atwood на ( http://howto.philippkeller.com/2005/04/24/Tags-Database-schemas/ ) очень полны (Она обсуждает достоинства 3 различных подходов схемы), и имеет хорошее решение для И запросы, которые будут обычно работать лучше, чем, что было упомянуто здесь до сих пор (т.е. она не использует связанный подзапрос на каждый термин). Также много хорошего материала в комментариях.

пикосекунда - подход, о котором все говорят здесь, упоминается как решение "Toxi" в статье.

12
задан Josh Lee 26 December 2010 в 14:35
поделиться

2 ответа

Использование приведения - НАМНОГО лучший подход, чем обезьяна исправление основного класса:

class Vec3
    attr_accessor :x,:y,:z

    def *(a)
        if a.is_a?(Numeric) #multiply by scalar
            return Vec3.new(@x*a, @y*a, @z*a)
        elsif a.is_a?(Vec3) #dot product
            return @x*a.x + @y*a.y + @z*a.z
        end
    end

    def coerce(other)
        return self, other
    end
end

если вы определите v как v = Vec3.new , то будет работать следующее: v * 5 и 5 * v Первый элемент, возвращаемый coerce (self), становится новым получателем для операции, а второй элемент (other) становится параметром, поэтому 5 * v в точности эквивалентен v * 5

22
ответ дан 2 December 2019 в 07:21
поделиться

Я считаю, что следующее будет делать то, что вы хотите, хотя предложение перил использовать принуждение вместо обезьяньего исправления Числовое является предпочтительным методом. Используйте этот метод только в случае необходимости (например, если вы хотите, чтобы некоторые двоичные операнды были транзитивными).

Fixnum.class_eval do
  original_times = instance_method(:*)
  define_method(:*) do |other|
    if other.kind_of?(Vec3)
      return other * self
    else
      return original_times.bind(self).call(other)
    end
  end
end
-1
ответ дан 2 December 2019 в 07:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: