问题
Consider this:
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
Is there some way to check if all public attributes are equal in classes of same type?
回答1:
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
回答2:
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 defines ==, eql?, and hash for you, so that two Aaas are equal, if their values for a and b are equal. It also defines initialize so that you can optionally pass in the values for a and b when creating the object (Aaa.new(value_for_a, value_for_b)). And it defines to_a to return [a,b].
You can also use Struct.new with a block to define additional methods, so you have the full power of a "normal" class:
Aaa = Struct.new(:a, :b) do
def c
a+b
end
end
Aaa.new(23,42).c #=> 65
回答3:
We can easily generalize to any number of instances and drop the requirement for getters for the instance variables:
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
Change z to:
z = Aaa.new(1,2,4)
then:
x.instance_variables.map do |v|
arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1
end.all?
#=> false
回答4:
Extra method to deal with comparing objects in Ruby consists in using hash. For performance reason, when the class are huge, the best is to use hash to compare ruby objects as so :
class Aaa attr_accessor :a, :b
def intialize(value_a,value_b) @a = value_a @b = value_b end
def hash(target) @a.hash == target.a.hash && @b.hash == target.b.hash end end
A = new Aaa('whatever','whenever') B = new Aaa('however','whoever') A.hash(B)
来源:https://stackoverflow.com/questions/3941074/comparing-objects-in-ruby