加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 主模块中名为`hash`的方法覆盖了某个对象的`hash`方法

发布时间:2020-12-17 03:33:14 所属栏目:百科 来源:网络整理
导读:鉴于此脚本 def hash puts "why?"endx = {}x[[1,2]] = 42 它输出以下内容 why?/tmp/a.rb:6:in `hash': no implicit conversion of nil into Integer (TypeError) from /tmp/a.rb:6:in `main' 在这种情况下,似乎脚本中定义的散列函数覆盖了Array #hash.由于我
鉴于此脚本

def hash
  puts "why?"
end

x = {}
x[[1,2]] = 42

它输出以下内容

why?
/tmp/a.rb:6:in `hash': no implicit conversion of nil into Integer (TypeError)
    from /tmp/a.rb:6:in `<main>'

在这种情况下,似乎脚本中定义的散列函数覆盖了Array #hash.由于我的哈希方法的返回值是nil而不是Integer,因此它会抛出异常.以下脚本似乎证实了这一点

puts [1,2,3].hash

def hash
  puts "why?"
end

puts [1,3].hash

输出是

-4165381473644269435
why?
/tmp/b.rb:6:in `hash': no implicit conversion of nil into Integer (TypeError)
    from /tmp/b.rb:6:in `<main>'

我试着查看Ruby源代码,但无法弄清楚为什么会发生这种情况.这种行为是否有记录?

解决方法

你没有重写Array #hash,你通过创建Object #hash来隐藏Kernel #hash:

puts method(:hash)
def hash   
  puts "why?"
end
puts method(:hash)

打印:

#<Method: Object(Kernel)#hash>
#<Method: Object#hash>

修复它,以便我们可以看到更多:

def hash
  puts "why?"
  super
end

x = {}
x[[1,2]] = 42

现在的输出是:

why?
why?

没有错误.尝试使用x [[1,3,4,5,6,7]] = 42,你会看到为什么?打印七次.对于每个数组元素,因为数组的哈希方法使用其元素的哈希值.并且Integer #hash不存在,它从Object / Kernel继承了它的hash方法,因此你的使用会被使用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读