使用自定义规则设置

apn*_*ing 5 ruby ruby-on-rails

根据Set doc,使用集合中的元素进行比较eql?.

我有一个类:

class Foo
  attr_accessor :bar, :baz

  def initialize(bar = 1, baz = 2)
    @bar = bar
    @baz = baz
  end

  def eql?(foo)
    bar == foo.bar && baz == foo.baz
  end
end
Run Code Online (Sandbox Code Playgroud)

在控制台中:

f1 = Foo.new
f2 = Foo.new
f1.eql? f2 #=> true
Run Code Online (Sandbox Code Playgroud)

但...

 s = Set.new
 s << f1
 s << f2
 s.size #=> 2
Run Code Online (Sandbox Code Playgroud)

因为f1等于f2,s应该包括它们.

如何set使用自定义规则制作拒绝元素?

Phr*_*ogz 7

您链接的文档明确说明(强调我的):

每个元素的相等性是根据Object#eql?
Object#hash确定的,因为SetHash用作存储.

如果hash向类中添加一个返回eql?对象相同值的方法,它的工作原理如下:

# With your current class

f1, f2 = Foo.new, Foo.new
p f1.eql?(f2)
#=> true
p f1.hash==f2.hash
#=> false
p Set[f1,f2].length
#=> 2

# Fix the problem
class Foo
  def hash
    [bar,hash].hash
  end
end

f1, f2 = Foo.new, Foo.new
p f1.eql?(f2)
#=> true
p f1.hash==f2.hash
#=> true
p Set[f1,f2].length
#=> 1
Run Code Online (Sandbox Code Playgroud)

说实话,当涉及多个值时,我从未对如何编写好的自定义hash方法有很好的理解.

  • 你不能只用`[bar,baz] .hash`作为哈希吗? (3认同)