为啥不推荐使用 Enumerable#each_with_object ?

Posted

技术标签:

【中文标题】为啥不推荐使用 Enumerable#each_with_object ?【英文标题】:Why is Enumerable#each_with_object deprecated?为什么不推荐使用 Enumerable#each_with_object ? 【发布时间】:2011-07-25 18:12:34 【问题描述】:

根据APIdock,Ruby 方法Enumerable#each_with_object 已弃用。

除非是错误的(说“在最新的稳定版 Rails 上已弃用”让我怀疑可能是 Rails 的猴子补丁被弃用了),为什么它会被弃用?

【问题讨论】:

【参考方案1】:

这是对您问题预设的否定的回答,也是为了确定它是什么。


each_with_object 方法可以为您节省额外的击键次数。假设您要从数组中创建一个散列。使用inject,您需要一个额外的h

array.inject()|h, a| do_something_to_h_using_a; h # <= extra `h` here

但是使用each_with_object,您可以保存输入:

array.each_with_object()|a, h| do_something_to_h_using_a # <= no `h` here

所以尽可能使用它是好的,但是有一个限制。正如我在“How to group by count in array without using loop”中也回答的那样,

当初始元素是可变对象时,例如ArrayHashString,您可以使用each_with_object

当初始元素是Numeric不可变对象时,必须使用inject

sum = (1..10).inject(0) |sum, n| sum + n # => 55

【讨论】:

+1 - 感谢您澄清 each_with_object 和 inject 之间的区别! 根据this source,each_with_object 不仅仅是保存击键,它实际上是一个更有效的注入版本,因为它在每次迭代中重复使用相同的对象,而不是创建一个新对象。 您确实知道第二个版本有 7 个额外字符,对吧?因此,当您说each_with_object 可以节省您的击键次数时,我希望第二个版本的字符更少。不是这样的。 @CosminAtanasiu “保存击键”是你说的,不是我说的。【参考方案2】:

嗯,这似乎有点奇怪。

即使是敏捷 Rails 也会在某处写到:

“Ruby 1.9 each_with_object 方法被发现非常方便,以至于 Rails 工作人员为您将其反向移植到 Ruby 1.8”。

这似乎是 APIdock 中的错误?我看不出有什么理由。

【讨论】:

我同意,它真的很方便。如果它被弃用,我只会将我自己的添加到我找到的每个 Ruby 中! :) 有趣,我想我前几天刚在 1.9 Pick Axe 书中读到了这个。【参考方案3】:

Ruby 主干源代码中没有注释,方法 仍然存在(与该页面的声明相反),并且在我能找到的邮件列表中没有提及它。

APIdock 简直是一头雾水。 APIdock 说它已被弃用的地方实际上是标准库中具有该方法的最早版本(而不仅仅是一个 ActiveSupport 反向端口扩展),如果您使用的是具有该方法的 Ruby,Rails 会禁用它的版本,所以 APIdock似乎对项目之间迁移的方法感到困惑。

【讨论】:

以上是关于为啥不推荐使用 Enumerable#each_with_object ?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Enumerable 不继承自 IEnumerable<T>

为啥 Enumerable 中的方法返回 Enumerator?

为啥 enumerable: false 不会级联到 TypeScript 中的继承类?

为啥重复 Enumerable 到 Observable 转换块

为啥 Enumerable 在 Ruby 中没有长度属性?

为啥 Enumerable.Range 实现 IDisposable?