Range#include 的最小接口?支持
我想让我的一年的日期班级播放 range#include?,根据文档,它必须实现的只是
< =>
:
class Count
include Comparable
attr_reader :value
def initialize(value)
@value = value
end
def <=>(other)
value <=> other.value
end
end
让我们尝试Ruby 3.1.1:
(Count.new(1)..Count.new(5)).include? Count.new(3)
# => in `each': can't iterate from Count (TypeError)
我不明白为什么它在此处尝试迭代,每个
不需要弄清楚包含。
知道我在这里做错了什么?感谢您的提示!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该文档不正确或(我怀疑)过时。
按照您期望的方式[ Bold 强调我]:
范围#cover#cover#
range#rangage#包括吗?
包含一个不祥的陈述[粗体重点]在这里您可以看到差异:
范围#cover?
评估true
,因为'a'&lt; ='cc'&amp;&amp; 'cc'&lt; ='d'
,而范围#include?评估
false
是因为('a'a'..'d') 。
是假的。请注意,使用在规格中明确特殊。。
那里 is 一个说明
范围#include?和
范围#cover?
使用&lt; =&gt;
的规格仅使用
和integer
S上面的不祥文档<代码>范围#包括?范围#封面?
行为相同。对于
range> s,有很多特殊casing正在进行中,这不是第一次导致错误和/或非直觉行为:
in
range> range ynage> range prange> range
的不必要检查href =“ https://github.com/ruby/spec/pull/852” rel =“ nofollow noreferrer”> https://github.com/ruby/spec/pull/pull/852 / https://github.com/ruby/ruby/ruby/pull/pull/pull/4928我个人不是这是所有这些特殊观念的忠实拥护者。我认为这样做是出于绩效原因,但是获得更好的性能的方法不是在语言规范中添加怪异的特殊情况,而是删除它们,这使语言变得更简单,因此更容易优化。 。或者,换句话说:在任何给定的时间点,编译器作者可以花费时间来实施奇怪的特殊情况或出色的优化,但不会两者兼而有之。 Xruby,Ruby.net,Macruby,Maglev,Jruby,Ironruby,Truffleruby,Rubinius,Topaz和Friends表明,获得高性能Ruby的方法是强大的编译器,不是怪异的手工滚动的专用C代码。
我会文件bug 文档和规格。
The documentation is incorrect or (rather, I suspect) outdated.
Range#cover?
works the way you expect [bold emphasis mine]:The documentation for
Range#include?
contains a somewhat ominous statement [bold emphasis mine]:Here you can see the difference:
Range#cover?
evaluates totrue
because'a' <= 'cc' && 'cc' <= 'd'
, whereasRange#include?
evaluates tofalse
because('a'..'d').to_a == ['a', 'b', 'c', 'd']
and thus('a'..'d').each.include?('cc')
is falsey.Note that the introductory example using
Time
still works becauseTime
is explicitly special-cased in the spec.There is a spec which says both
Range#include?
andRange#cover?
use<=>
, but it is only tested withInteger
s, for which we know from the ominous documentation above thatRange#include?
andRange#cover?
behave the same.There is quite a lot of special-casing going on for
Range
s and it is not the first time this has led to bugs and/or non-intuitive behavior:Time
inRange#each
as per the comment / https://github.com/ruby/spec/pull/852 / https://github.com/ruby/ruby/pull/4928Personally, I am not a big fan of all this special-casing. I assume it is done for performance reasons, but the way to get better performance is not to add weird special cases to the language specification, it is to remove them which makes the language simpler and thus easier to optimize. Or, put another way: at any given point in time, a compiler writer can either spend the time implementing weird special cases or awesome optimizations, but not both. XRuby, Ruby.NET, MacRuby, MagLev, JRuby, IronRuby, TruffleRuby, Rubinius, Topaz, and friends have shown that the way to get high-performance Ruby is a powerful compiler, not weird hand-rolled special-cased C code.
I would file a bug, if only to get some clarification into the docs and specs.