gpt4 book ai didi

ruby - 为什么 Enumerator 包含 Enumerable

转载 作者:数据小太阳 更新时间:2023-10-29 08:39:04 26 4
gpt4 key购买 nike

挖掘这个,这是一个很酷的 Enumerator(惰性序列)从 1 到(Ruby 可以表示的最大 Float):

1.9.3-p327 :014 > e = (1..Float::INFINITY).each

看看我们如何捕获序列的前面:

1.9.3-p327 :015 > e.first
=> 1
1.9.3-p327 :016 > e.take(2)
=> [1, 2]

这是好东西吧?我也这么认为。但是然后这个:

1.9.3-p327 :017 > e.drop(2).first

进入拉拉大陆。我的意思是它不会在 5 秒内返回。

哦,这是一个线索:

1.9.3-p327 :020 > p e.method(:drop)
#<Method: Enumerator(Enumerable)#drop>

Enumerator (e) 似乎从 Enumerable(模块)中获得了 #drop 方法,并混入了 枚举器(类)。现在,为什么 Ruby 会去将 Enumerable 混合到 Enumerator 中?我不知道。但它就在那里,记录在 Enumerator in Ruby 1.9.3 中和 Enumerator in Ruby 2.0 .

我看到的问题是 Enumerable 中定义的某些方法在 Enumerator 上工作或在某种程度上工作。示例包括 #first#take。至少还有一个:#drop 不起作用。

在我看来,Enumerator 包括 Enumerable 是一个错误。你怎么看?

请注意,Ruby 2.0 定义了 Enumerator::Lazy(Enumerator 的子类),它定义了一堆 Enumerable 方法,始终是惰性的.这里有股腥味。为什么混合非惰性方法和在某些情况下损坏的方法(进入 Enumerator)只是为了转身并在(Enumerator)的子类中提供惰性替代方案?

另见:

1.9.3-p327 :018 > p e.method(:first)
#<Method: Enumerator(Enumerable)#first>
1.9.3-p327 :020 > p e.method(:drop)
#<Method: Enumerator(Enumerable)#drop>

最佳答案

这也是许多其他集合框架所共有的设计选择。

Ruby 的集合操作不是类型保留的。它们总是返回一个Array,不管它们被调用的是什么类型的集合。这也是例如 .NET 所做的,除了类型始终是 IEnumerable,这两者都更有用(因为更多的东西可以表示为 IEnumerable 而不是一个 Array,例如无限序列),同时不太有用(因为 IEnumerable 的接口(interface)比 Array 的接口(interface)小得多,所以您可以对其执行的操作较少)。

这允许 Ruby 的集合操作一次实现,而无需重复。

这也意味着将您自己的集合集成到 Ruby 的集合框架中非常容易:只需实现 each,混入 Enumerable 即可。如果 Ruby 的 future 版本添加了新的集合方法(例如 Ruby 1.9 中的 flat_map),您不必任何,它也适用于您的集合.

另一种设计选择是使所有集合操作保持类型。因此,所有集合操作都会返回调用它们的类型。

有一些语言可以做到这一点。然而,它是通过将所有集合方法复制并粘贴到所有集合类中来实现的,即大量代码重复。

这意味着如果你想将自己的集合添加到集合框架中,你必须实现集合协议(protocol)的每一个方法。如果该语言的 future 版本添加了新方法,那么您必须发布新版本的集合。

Scala 2.8 的集合框架是第一次有人想出如何在不重复代码的情况下进行类型保留集合操作。但那是在 Ruby 的集合框架设计出来很久之后。在设计 Ruby 的集合框架时,根本不知道如何在不重复代码的情况下进行类型保留集合操作,而 Ruby 的设计者选择了不重复。

从 Ruby 1.9 开始,实际上有一些重复。某些 Hash 方法被复制以返回 Hash 而不是 Array。您已经提到了 Ruby 2.0 的 Enumerator::Lazy,它复制了许多 Enumerable 方法以返回 Enumerator::Lazy

可以使用 Scala 在 Ruby 中使用的相同技巧,但它需要对集合框架进行彻底改造,这将使每个现有的集合实现都过时。 Scala 之所以能够做到这一点,是因为当时几乎没有任何用户群。

关于ruby - 为什么 Enumerator 包含 Enumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15938203/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com