Сравнение объектов в рубине - PullRequest
6 голосов
/ 15 октября 2010

Учтите это:

class Aaa
  attr_accessor :a, :b
end

x = Aaa.new
x.a, x.b = 1,2
y = Aaa.new
y.a, y.b = 1,2

puts x == y #=>false

Есть ли способ проверить, все ли открытые атрибуты равны в классах одного типа?

Ответы [ 4 ]

8 голосов
/ 15 октября 2010
Aaa = Struct.new(:a, :b)

x = Aaa.new
x.a, x.b = 1,2
y = Aaa.new
y.a, y.b = 1,2

x == y #=> true

Struct определяет для вас ==, eql? и hash, так что два Aaa равны, если их значения для a и b равны. Он также определяет initialize, так что вы можете при желании передать значения для a и b при создании объекта (Aaa.new(value_for_a, value_for_b)). И он определяет to_a для возврата [a,b].

Вы также можете использовать Struct.new с блоком для определения дополнительных методов, поэтому у вас есть все возможности "нормального" класса:

Aaa = Struct.new(:a, :b) do
  def c
    a+b
  end
end
Aaa.new(23,42).c #=> 65
7 голосов
/ 15 октября 2010
class Aaa
  attr_accessor :a, :b

  def ==(other)
    return self.a == other.a && self.b == other.b
  end
end

x = Aaa.new
x.a,x.b = 1,2
y = Aaa.new
y.a,y.b = 1,2
y = Aaa.new
y.a,y.b = 1,2
z = Aaa.new
z.a,z.b = 1,3

x == y # => true
x == z # => false
1 голос
/ 30 июля 2015

Мы можем легко обобщить любое число экземпляров и отбросить требование для получателей для переменных экземпляра:

class Aaa
  def initialize(a,b,c)
    @a, @b, @c = a, b, c
  end
end

x = Aaa.new(1,2,3)
y = Aaa.new(1,2,3)
z = Aaa.new(1,2,3)
arr = [x,y,z]

x.instance_variables.map do |v|
  arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1
end.all?
  #=>true

Изменить z на:

z = Aaa.new(1,2,4)

затем:

x.instance_variables.map do |v|
  arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1
end.all?
  #=> false
0 голосов
/ 11 августа 2013

Дополнительный метод для сравнения объектов в Ruby состоит в использовании hash. По причинам производительности, когда класс огромен, лучше всего использовать hash для сравнения объектов ruby ​​следующим образом:

класс ААА attr_accessor: a,: b

def intialize (value_a, value_b) @a = значение_a @b = значение_b конец

def hash (target) @ a.hash == target.a.hash && @ b.hash == target.b.hash конец конец

A = новый Aaa («что угодно», «всякий раз») B = новый Aaa («однако», «кто бы ни») A.hash (В)

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