Ruby 一组字符串和重新打开的字符串

Ruby 一组字符串和重新打开的字符串,ruby,Ruby,为了回答这个问题,我尝试使用集合和字符串,试图得到一组不区分大小写的字符串。但由于某种原因,当我重新打开String类时,当我向集合中添加字符串时,不会调用任何自定义方法。在下面的代码中,我没有看到任何输出,但我希望至少调用一个重载的运算符。为什么会这样 编辑:如果我创建一个自定义类,比如String2,在这里我定义了一个散列方法,等等,当我将我的对象添加到一个集合中时,这些方法会被调用。为什么不用绳子 require 'set' class String alias :compare_o

为了回答这个问题,我尝试使用集合和字符串,试图得到一组不区分大小写的字符串。但由于某种原因,当我重新打开String类时,当我向集合中添加字符串时,不会调用任何自定义方法。在下面的代码中,我没有看到任何输出,但我希望至少调用一个重载的运算符。为什么会这样

编辑:如果我创建一个自定义类,比如String2,在这里我定义了一个散列方法,等等,当我将我的对象添加到一个集合中时,这些方法会被调用。为什么不用绳子

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'
require'set'
类字符串
别名:比较源代码:
def v
p“
downcase.compare\u orig v.downcase
结束
别名:eql_orig:eql?
DEFEQL?v
p‘eql?’
eql_原v
结束
别名:hash_orig:hash
def散列
p'哈希'
downcase.hash_orig
结束
结束
Set.new查看for
集合
,它使用一个简单的散列来存储:

def add(o)
  @hash[o] = true
  self
end
因此,看起来您需要做的不是打开
String
而是打开
Set
。我还没有测试过这个,但它应该会给你一个正确的想法:

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

如评论中所述,这可以通过更简单的方式实现:

class MySet < Set
  def add(o)
    super(o.is_a?(String) ? o.downcase : o)
  end
end
class MySet
一个简单的
超级(o.is\u A?(字符串)?o.downcase:o)
可能是个更好的主意。谢谢。行得通,是的。如果我创建了一个自定义类,比如String2,在这里我定义了一个散列方法,等等,当我将我的对象添加到一个集合中时,这些方法确实会被调用。为什么?(我编辑了我的问题)。Ruby源代码()可能会提供一些线索。看起来
String
s在MRI中作为散列键得到了特殊处理。