Есть ли идиома, чтобы получить элемент тождественности (0,1) для операции (: +,: *) над объектом Ruby? - PullRequest
0 голосов
/ 22 февраля 2012

Учитывая определенный объект, который respond_to? :+ Я хотел бы знать, что это за элемент идентификации для этой операции над этим объектом.Например, если a равно Fixnum, то для операции :+ должно быть указано 0, поскольку a + 0 == a для любого Fixnum.Конечно, я уже знаю элемент идентификации для :+ и :*, когда речь идет о Fixnum s, но есть ли какой-нибудь стандартный шаблон / идиома для динамического получения их для всех числовых типов и операций ?.

Более конкретно, я написал некоторый код (см. Ниже), чтобы вычислить кратчайший путь между v1 и v2 (вершинами в графе), где стоимость / расстояние / вес каждого ребра в графе задается пользователем.указанный тип.В текущей реализации стоимость / вес ребер может быть Fixnum, Float или чем-либо, что реализует Comparable и может добавить 0 к себе и вернуть self.

НоМне было интересно, что является лучшим шаблоном:

  • , требующий, чтобы используемый тип должен поддерживать a + 0 == a
  • , требующий, чтобы этот тип предоставлял какое-то дополнительное обнаружение элемента идентификации 'a.class ::ADDITION_IDENTITY_ELEMENT
  • ??

My Реализация алгоритма Дейкстры

  def s_path(v1,v2)
    dist = Hash.new { nil}
    pred = {}
    dist[v1] = 0 # distance from v1 to v1 is zero
    #pq = nodes 
    pq = [v1]

    while u = pq.shift
      for edge in from(u)
        u,v,cost = *edge
        new_dist = cost + dist[u]  
        if dist[v].nil? or new_dist < dist[v]
          dist[v] = new_dist
          pred[v] = u
          pq << v
        end
      end
    end
    path = [v2]
    path << pred[path.last] while pred[path.last]
    path.reverse
  end

1 Ответ

1 голос
/ 22 февраля 2012

Я думаю, что a.class::ADDITION_IDENTITY_ELEMENT довольно хорошо, за исключением того, что я бы назвал его a.class::Zero.

Другой вариант - сделать (a-a).

Лично я бы не стал пытатьсясделайте вещи настолько абстрактными, и я бы просто потребовал, чтобы каждое расстояние было Numeric (например, Float или Integer).Тогда вы можете просто продолжать использовать 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...