- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
在this presentation演讲者创建了一个值(value)类。
在实现它时,他重写了#eql?
,并说在Java开发中,惯用语是每当你重写#eql?
时,你必须重写#散列
。
class Weight
# ...
def hash
pounds.hash
end
def eql?(other)
self.class == other.class &&
self.pounds == other.pounds
end
alias :== eql?
end
首先,什么是#hash
方法?我可以看到它返回一个整数。
> 1.hash
=> -3708808305943022538
> 2.hash
=> 1196896681607723080
> 1.hash
=> -3708808305943022538
使用 pry 我可以看到一个整数响应 #hash
但我看不到它从哪里继承方法。它不是在 Numeric
或 Object
上定义的。如果我知道这个方法做了什么,我可能会理解为什么它需要与 #eql?
同时被覆盖。
那么,为什么每次覆盖 eql?
时都需要覆盖 #hash
?
最佳答案
Firstly, what is the
#hash
method? I can see it returns an integer.
#hash
方法应该返回接收者的哈希值。 (该方法的名称有点随意)。
Using pry I can see that an integer responds to
#hash
but I cannot see where it inherits the method from.
[so] 上有几十个“这个方法从哪里来”类型的问题,答案总是一样的:知道一个方法从哪里来的最好方法就是简单地问它:
hash_method = 1.method(:hash)
hash_method.owner #=> Kernel
因此,#hash
继承自Kernel
。但是请注意,Object
和 Kernel
之间存在一些特殊的关系,因为在 Kernel
中实现的一些方法记录在Object
反之亦然。这可能有历史原因,现在是 Ruby 社区生活中一个不幸的事实。
不幸的是,由于我不明白的原因,the documentation for Object#hash
于 2017 年在 commit ironically titled "Add documents" 中删除.然而,它是 still available in Ruby 2.4 (大胆强调我的):
hash
→integer
Generates an Integer hash value for this object. This function must have the property that
a.eql?(b)
impliesa.hash == b.hash
.The hash value is used along with eql? by the Hash class to determine if two objects reference the same hash key. […]
因此,如您所见,#eql?
和 #hash
之间存在着深刻而重要的关系,事实上,使用 的方法的正确行为code>#eql?
和 #hash
取决于维持这种关系的事实。
因此,我们知道该方法称为 #hash
,因此很可能会计算哈希值。我们知道它与 eql?
一起使用,我们知道它特别被 Hash
类使用。
它到底有什么作用?好吧,我们都知道哈希函数是什么:它是一种将更大的、可能无限的输入空间映射到更小的、有限的输出空间的函数。特别是,在这种情况下,输入空间是所有 Ruby 对象的空间,输出空间是“快速整数”(即过去称为 Fixnum
的整数)。
我们知道哈希表是如何工作的:值根据它们的键的哈希值放在桶中,如果我想找到一个值,那么我只需要计算键的哈希值(很快)和知道我在哪个桶中找到值(value)(在恒定时间内),而不是例如一个键值对数组,我需要将键与数组中的每个键进行比较(线性搜索)以找到值。
但是,有一个问题:由于哈希的输出空间小于输入空间,所以有不同的对象具有相同的哈希值,因此最终在同一个桶中。因此,当两个对象具有不同的哈希值时,我知道它们是不同的事实,但如果它们具有相同的哈希值,那么它们仍然可能不同,我需要比较它们以确定是否相等——这就是哈希和相等性之间的关系从何而来。另请注意,当同一个存储桶中有许多键和向上键时,我将不得不再次将搜索键与存储桶中的每个键进行比较(线性搜索)以找到值。
从所有这些我们可以得出 #hash
方法的以下属性:
Integer
。Fixnum
)。Hash
可能会退化为性能极低的链表。)Hash
退化为链表,作为服务降级攻击的一种形式。)关于Ruby:为什么每次覆盖 `#hash` 时都需要覆盖 `#eql?`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54961311/
Ruby里面有4种比较方法,equal?, eql?, ==, ===,而且在不同的类里面表现的很不一样。在使用的时候也特别容易搞糊涂。 这篇博文将演示一些代码来讲解各个方法。 == - 类意义上
我正在测试 node.js 程序中的一个函数,它应该将一些数据保存到 mongo 数据库中。我正在使用 mocha、chai 和 should。 在模式中,我定义了要保存的数据 data: [{typ
当我使用 .match 和 .eql 时?对于字符串比较,他们给出了不同的结果 text_from_page = "wrong length (should be 64 characters)" er
在this presentation演讲者创建了一个值(value)类。 在实现它时,他重写了#eql?,并说在Java开发中,惯用语是每当你重写#eql?时,你必须重写#散列。 class Weig
在 RSpec 中,使用 should == ... 和 should eql(...) 有什么区别?我注意到 RSpec 文档总是使用 eql,但是 == 更少打字而且更容易阅读。我错过了什么? 最
我在 String 类的文档中读到 eql? 是一个严格的相等运算符,没有类型转换,而 == 是一个试图转换的相等运算符其次,它的参数是一个字符串,而且,这个方法的 C 源代码确认: eql?源代码:
我试图了解这四种方法之间的区别。我知道默认情况下 == 调用方法 equal? 当两个操作数引用完全相同的对象时返回 true。 === 默认也会调用 == 调用 equal?...好吧,如果这三个方
你可以做什么的例子。 (defmethod some-fn ((num real)) (print "an integer")) (defmethod some-fn ((num real))
每个人都知道,Nest Elasticsearch对要查找的东西进行澄清的查询并不容易且很无聊。我也为这个问题感到困惑。结果,我无法在查询中使用“不为空”和null。 var list = cl
前几天了解了defmethod的eql子句参数规范语法。 The defmethod hyperspec清楚地表明 eql 的存在token 是语法的基本部分。例如,当我在 CLISP 中尝试以下操作
我在 Ruby 中看到了很多平等的概念。 == eql? === equal? 而且它们都有不同的语义。对我来说应该只有两个,一个是引用相等,另一个是值相等。我不明白为什么 Ruby 需要 eql?
我有一个获取 ActiveRecord 范围的 Controller 索引测试。测试目前看起来像这样(包括一些内联调试的东西): describe "GET index" do it "assig
我想知道,根据#eql,当我将相同的键放入数组(这是哈希的键)时,为什么这个 ruby 哈希的计算结果为 nil?并检查哈希是否相等。 some_arr = [1] => [1] my_hash
Common Lisp 中是否有等于任何原子的通配符? 也就是说,有没有这样的通配符 (eql wildcard any-atom) 返回真值? 最佳答案 函数atom如果它的参数是一个原子,则返回
在编写带有大量实例变量的大类时,写==、eql?和哈希方法是一个很大的麻烦。有没有办法制作一个“模板类”来自动化这个过程?或者用任何其他方式。 例子: class Template def =
在 rspec 测试中使用 eq 和 eql 有什么区别?有区别吗: it "adds the correct information to entries" do # book = Addres
我正在处理一个 API 项目并使用 Postman 来测试 API。我写了几个测试用例来检查 null 如下, //user id is present pm.test("user id is pre
我有一个包含“搜索字段”和“搜索按钮”的页面以及一个包含 5 列的表格。我想使用 testcafe + javascript 进行自动化测试,如下所示: 1:输入“搜索字段”——完成 2:点击“搜索按
我有一个关于用于单元测试的 Chai 库的问题。我注意到一条声明说: equal : 断言目标严格 (===) 等于给定值。 eql : 断言目标深度等于值。 我对strictly 和deeply 之
我使用的是 Ruby 2.2.1,遇到以下情况: a = ... # some object h = ... # some hash p h.size #=> 1 p h.keys.first.has
我是一名优秀的程序员,十分优秀!