a set of strings and reopening String

In an attempt to answer this question: How can I make the set difference insensitive to case?, I was experimenting with sets and strings, trying to have a case-insensitive set of strings. But for some reason when I reopen String class, none of my custom methods are invoked when I add a string to a set. In the code below I see no output, but I expected at least one of the operators that I overloaded to be invoked. Why is this?

EDIT: If I create a custom class, say, String2, where I define a hash method, etc, these methods do get called when I add my object to a set. Why not String?

require 'set'

class String
  alias :compare_orig :<=>
  def <=> v
    p '<=>'
    downcase.compare_orig v.downcase
  end

  alias :eql_orig :eql?
  def eql? v
    p 'eql?'
    eql_orig v
  end

  alias :hash_orig :hash
  def hash
    p 'hash'
    downcase.hash_orig
  end
end

Set.new << 'a'

Looking at the source code for Set , it uses a simple hash for storage:

def add(o)
  @hash[o] = true
  self
end

So it looks like what you need to do instead of opening String is open Set . I haven't tested this, but it should give you the right idea:

class MySet < Set
  def add(o)
    if o.is_a?(String)
      @hash[o.downcase] = true
    else
      @hash[o] = true
    end
    self
  end
end

Edit

As noted in the comments, this can be implemented in a much simpler way:

class MySet < Set
  def add(o)
    super(o.is_a?(String) ? o.downcase : o)
  end
end
链接地址: http://www.djcxy.com/p/67764.html

上一篇: 如何检测通知区域的位置?

下一篇: 一组字符串并重新打开String