Объект Ruby, сравнимый с Fixnum - PullRequest
       1

Объект Ruby, сравнимый с Fixnum

2 голосов
/ 09 декабря 2010

Я хотел бы реализовать класс в Ruby, который сопоставим (используя оператор <=>) с любым Fixnum, и наоборот . Это в конечном итоге будет использоваться в диапазоне. Вот схема моего класса:

class N
  include Comparable
  attr :offset
  def initialize(offset = 0)
    @offset = offset
  end
  def succ
    N.new(@offset + 1)
  end
  def +(offset)
    N.new(@offset + offset)
  end
  def <=>(other)
    return @offset <=> other.offset if other.kind_of? N
    return 1  # N is greater than everything else
  end
end

def n; N.new(0); end

Теперь это прекрасно работает при использовании в n..n+2 и n..999, но не в 1..n. Это связано с тем, что n <=> 1 работает, а 1 <=> n - нет (возвращает ноль ).

Есть ли способ заставить Fixnum рассматривать мой класс N как сопоставимый объект? Ваши мысли приветствуются:)

Ответы [ 2 ]

6 голосов
/ 09 декабря 2010

Если вы хотите реализовать свой собственный тип номера, вы должны внедрить coerce:

class N
  def coerce(other)
    return N.new(other), self
  end
end

n = N.new

1 <=> n # => -1

Все встроенные типы номеров Ruby в базовой библиотеке, все типы номеров в стандартной библиотеке, а также все сторонние типы номеров используют протокол coerce для поиска общего типа, чтобы сделать такие операторы, как +, * и == коммутативно и -, / и <=> симметрично.

Мне не совсем понятно, какой должна быть семантика N, поэтому приведенная выше реализация является лишь примером.

0 голосов
/ 09 декабря 2010

Ладно, я сделал небольшое обезьянье исправление ( свобода исправление;), которое, похоже, решило мою проблему на данный момент.

class Fixnum
  def <=>(other)
    return -1 if other.kind_of? N
    return -1 if self < other
    return 0 if self == other
    return 1 if self > other
  end
end

Вывод выглядит так, как ожидалось, и, насколько я могу судить, ничего не нарушает внутреннюю работу Fixnum. Любые лучшие идеи / комментарии, не стесняйтесь размещать их.

1 <=> n # => -1
1 <=> 1 # => 0
1 <=> 2 # => -1
2 <=> 1 # => 1
1 == 1  # => true
1 == 2  # => false
1 < 2   # => true
1 > 2   # => false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...