Ruby 的 Enumerator 对象如何在内部迭代器上进行外部迭代?

2023-12-24

根据 Ruby 的文档,Enumerator 对象使用each方法(枚举)如果没有提供目标方法to_enum or enum_for方法。现在,让我们以下面的猴子补丁及其枚举器为例

o = Object.new
def o.each
    yield 1
    yield 2
    yield 3
end
e = o.to_enum

loop do
  puts e.next
end

鉴于 Enumerator 对象使用each何时回答的方法next被调用,如何调用each方法看起来像,每次next叫做? Enumeartor 类是否预加载了所有内容o.each并创建一个本地副本进行枚举?或者是否有某种 Ruby 魔法可以在每个yield 语句处挂起操作,直到next被调用到枚举器上?

如果制作了内部副本,那么它是深副本吗?可用于外部枚举的 I/O 对象又如何呢?

我正在使用 Ruby 1.9.2。


这并不完全是魔法,但它仍然很美丽。不是制作某种副本,而是Fiber http://www.ruby-doc.org/core-1.9.3/Fiber.html用于首先执行each在目标可枚举对象上。收到下一个对象后each, the Fiber产生这个对象,从而将控制权返回到Fiber最初已恢复。

它很漂亮,因为这种方法不需要可枚举对象的副本或其他形式的“备份”,正如人们可以想象的那样,例如通过调用#to_a于可数。与纤程的协作调度允许在需要时准确地切换上下文,而不需要保持某种形式的前瞻。

这一切都发生在C code https://github.com/ruby/ruby/blob/trunk/enumerator.c#L546-L605 for Enumerator。显示大致相同行为的纯 Ruby 版本可能如下所示:

class MyEnumerator
  def initialize(enumerable)
    @fiber = Fiber.new do
      enumerable.each { |item| Fiber.yield item }
    end
  end

  def next
    @fiber.resume || raise(StopIteration.new("iteration reached an end"))
  end
end

class MyEnumerable
  def each
    yield 1
    yield 2
    yield 3
  end
end

e = MyEnumerator.new(MyEnumerable.new)
puts e.next # => 1
puts e.next # => 2
puts e.next # => 3
puts e.next # => StopIteration is raised
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby 的 Enumerator 对象如何在内部迭代器上进行外部迭代? 的相关文章

  • Yield Return == IEnumerable 和 IEnumerator 吗?

    Is yield return实施的捷径IEnumerable and IEnumerator 是的 您可以在我的书 C in Depth 的第 6 章中找到更多相关信息 幸好第六章是免费提供 http www manning source
  • 创建自定义迭代器 Java?

    我对如何在 Java 中为类实现自定义迭代器有点困惑 我基本上需要创建一个 ArrayList 而不使用我已经可用的内置库 我了解创建类的基础知识 但我无法理解如何让迭代器适应所有这些 我有以下内容 我创建了一个实现可迭代接口的泛型类 它看
  • Ruby 中多维数组的帮助

    我有以下代码将字符串拆分为 3 个字节的组 str hello ix 0 iy 0 bytes tby str each byte do c if iy 3 iy 0 bytes ix tby each index do i bytes i
  • Rails 4 - 如何链接到 PDF 文件(名称.PDF)?

    我正在生成 PDF 文件 我的链接如下所示 当我点击这个时 它会带我去 display invoice 123456789 这是一个 HTML 版本 在控制器中的操作如下 def display invoice if params invo
  • 红宝石边缘情况

    ruby 有一些边缘情况很难解释 因为解析会带来一些有趣的问题 我在这里列出其中两个 如果您知道更多 请添加到列表中 def foo 5 end this one works if tmp foo puts tmp to s end How
  • 转储 YAML 时如何强制使用双引号?

    我有一个小脚本来自动化 YAML 文件中的一些操作 我读取原始 YAML 文件并将其转换为哈希 然后dump http ruby doc org stdlib 1 8 6 libdoc yaml rdoc YAML html method
  • Ruby 中的并行赋值运算符

    我正在查看 Ruby 编程 书中的一个示例 def fib up to max i1 i2 1 1 parallel assignment i1 1 and i2 1 while i1 lt max yield i1 i1 i2 i2 i1
  • 从 Ruby 中的 DateTime 变量获取时间

    我在 ruby 中工作 我有一个包含数据库中今天的日期时间的对象 我只想要时间截断数据 我怎样才能得到那个 Try 日期时间 strftime http www ruby doc org stdlib 1 9 3 libdoc date r
  • 预期的 ProductField,出现数组问题

    我有一个 Rails 4 应用程序 它有一个如下所示的 params 块 def store params params require store permit name description user id products attr
  • 如何计算带有偏移量的异或?

    我想用不同的偏移量进行异或计算以在计算中列出 例子 key 0 1 0 text 0 1 0 1 0 1 0 1 1 1 异或计算 key 0 text 0 key 1 text 1 key 2 text 2 key 0 text 3 ke
  • Ruby 枚举器中的“break”与“raise StopIteration”

    如果我使用 Ruby Enumerators 来实现生成器和过滤器 generator Enumerator new do y x 0 loop do y lt lt x x 1 break if x gt CUTOFF end end l
  • 在我的 ramaz 应用程序上显示 £ 符号时,我收到“不兼容的字符编码:CP850 和 UTF-8”

    显示时收到 不兼容的字符编码 CP850 和 UTF 8 我的 ramaz 应用程序上的符号 我怎样才能摆脱这个错误 我的 head 标签中有 UTF 8 元标签 当我输入 用键盘输入符号 看 我已将以下代码放入我的 ruby 文件中 但它
  • 如何从 ruby​​ 中的字符串名称创建类实例?

    我有一个类的名称 我想创建该类的一个实例 以便我可以循环该类的架构中存在的每个 Rails 属性 我该怎么做呢 我的名称是我想要检查的类的字符串 我想我需要实例化一个类实例 以便我可以 循环遍历它的属性并打印它们 在 Rails 中你可以这
  • Rails:named_scope、lambda 和块

    我认为以下两个是等效的 named scope admin lambda company id conditions gt company id company id named scope admin lambda do company
  • 已定义方法的 Ruby 钩子?

    我一直在谷歌上搜索这个问题 但找不到答案 这让我认为答案是否定的 但我想我会在这里问 以防有人确切知道 Ruby 是否有一个钩子来定义方法 即在模块或类上 如果没有 是否有人足够熟悉该实施的情况main对象以了解它到底如何将方法复制到Obj
  • 没有要加载的文件 - ffi_c (LoadError)

    这个问题困扰了我几天 每当我使用 bring to front 方法时 require rubygems require watir browser Watir Browser new browser bring to front 我收到此
  • Bundle 说 gem 丢失了 - 但事实并非如此?

    背景 我正在维护contentRuby On Rails 站点 但我确实没有 Rails 的经验 当尝试运行 Rails 服务器时 rails s我明白了 在任何来源中均找不到 activesupport 3 2 0 Run bundle
  • 在 ruby​​ 中下载多个 FTP 文件,如 d*.txt

    我需要连接到 ftp 站点并下载一堆名为 D txt 的文件 最多 6 个 你能帮我用 Ruby 编写这个代码吗 下面的代码只是 ftp Net FTP new ftp server site ftp login user pwd ftp
  • 红宝石接球和效率

    catch在 Ruby 中意味着跳出深度嵌套的代码 在 Java 中 例如用Java也可以达到同样的效果try catch用于处理异常 但它被认为是糟糕的解决方案 而且效率非常低 在 Ruby 中 我们有处理异常的方法begin raise
  • Rails/Ruby 合并两个具有相同键、不同值的哈希值

    我有两个想要合并的哈希值 它们看起来像这样 Hello gt 3 Hi gt 43 Hola gt 43 第二个哈希看起来像 Hello gt 4 Hi gt 2 Bonjour gt 2 我想合并这两个哈希数组 使结果看起来像 Hello

随机推荐

  • FFmpeg-Python 音频在最终视频中丢失

    我试图将视频放置在背景图像之上 但生成的输出视频没有音频 有什么办法可以让音频保持原样吗 def ConvertVideo source background start end dest stream ffmpeg input sourc
  • 奇怪的 while 语句行为?

    我不明白为什么以下陈述不起作用 randomKey random choice list topic keys randomValue random choice topic randomKey current len randomValu
  • 在一个 Android 应用程序中拥有多个 SQLiteOpenhelper

    我想知道是否可以在同一个 Android 应用程序中拥有多个 DbOpenHelper 但使用它们在同一个数据库中写入和读取 因为我试图从 2 个不同的 OpenHelper 具有不同的名称 创建表 但似乎只有第一个可以创建 当我尝试运行第
  • CKNotificationInfo soundName 不起作用

    Sbuscription 的创建如下 可以用 但是没有声音 为什么 医生说 if you specify the string default for this property the system plays the default a
  • 如何在Java中获取特定年份的所有星期日的日期?

    我正在认真寻找这段代码 我是新程序员 实际上我想让所有日期都带有标志 这些日期都是特定年份的星期日 请 我热切地等待您的回复 创建一个新日历 将时间设置为 1 1 yyyy 和某个时间 检查当前日期是否为星期日 然后向前滚动一天 直到星期日
  • 如何让 djangorestframework 使用格式后缀返回 xml?

    我可以让 djangorestframework 通过格式后缀 json 返回 json 但不能通过 xml 后缀返回 xml http 127 0 0 1 8000 chat rooms json id 1 timestamp 2013
  • memmem() STL 方式?

    是否有 STL 算法可用于像 memmem 一样搜索缓冲区内的字节序列 我不知道这是否是好的代码 但是以下代码可以使用std search http www cplusplus com reference algorithm search
  • Xcode 4.2 中的未知类型名称“命名空间”

    我正在编译QCAR SDK 但是当我向项目中添加更多框架后 它提示错误 Matrices h ifndef QCAR MATRIX H define QCAR MATRIX H namespace QCAR Matrix with 3 ro
  • PHP MP3 标签处理

    我有一个 php 脚本 我想提供其中的音乐列表 这些文件被命名为 01 mp3 02 mp3 和 03 mp3 等 他们都有标签信息 我的问题是如何在我的 php 脚本中访问它 您需要一个脚本来解析 mp3 文件以访问数据 来自谷歌 htt
  • 增量附加 numpy.arrays 到保存文件

    我已经尝试过 Hpaulji 概述的这种方法 但它似乎不起作用 如何在python中将多个numpy文件附加到一个numpy文件中 https stackoverflow com questions 42204368 how to appe
  • 在文本字段 Flutter 内部添加阴影

    我有这个设计 我想将其用于我的应用程序 但我不太确定如何添加框阴影 阴影位于文本字段的内部 请问有人可以给我一些帮助并为我指出如何执行此操作的正确方向吗 文本字段顶部的框阴影 干杯 杰克 您可以使用容器作为背景来实现这一点 例如使用线性 坡
  • 列表框 itemtemplate 内的绑定问题

    我有两个单独的列表框绑定问题 其中的 itemtemplate 包含一个文本框 1 一个列表框绑定到一串字符串 如何在创建的文本框中显示每个字符串并同时允许两种方式绑定 如果不指定 Path 或 XPath 则不允许进行双向绑定
  • NHibernate 从 SymbolSource.org 加载符号

    我希望能够调试 NHibernate 但我从未加载过任何符号SymbolSource org前 我需要在 Visual Studio 中输入什么 url 才能加载 NHibernate 的符号 以便我可以正确调试它 我正在运行 NHiber
  • 当内容扩展超过窗口大小时,在绝对定位元素上设置 100% 高度

    因此 在阅读 Stack Overflow 和网络之后 我发现实现 100 高度有两个主要技巧 在 HTML 和 BODY 上设置 height 100 Set your element to have either 高度 100 或 顶部
  • 无法以编程方式滚动到 JList 中的最后一项

    我有一个 JList 嵌套在 JScrollPane 中 当我向 JList 添加项目时 我希望 JScrollPane 自动滚动到 JList 的底部 以便最后一个项目可见 为此 我有以下代码 getWordListScroller ge
  • 在 Go 中要求 HTTP 基本身份验证的惯用方式?

    情况 我正在使用 Gorilla 的 mux 作为路由器构建 REST API 我想知道如何使用简单的 HTTP 基本身份验证来保护特定路由 我不需要从文件或任何外部源读取凭据 我真的只想通过硬编码的 HTTP 基本身份验证用户名和密码来保
  • ANTLR 入门并避免常见错误

    我已经开始学习 ANTLR 并且拥有 2007 年的书 The Definitive ANTLR Reference 和 ANTLRWorks 用于创建语法的交互式工具 而且 作为这样的人 我从第三章开始 针对不耐烦的人的快速浏览 这是一个
  • PBS 上的 Python 脚本失败,并显示错误 =>> PBS:作业被终止:ncpus 37.94 超出限制 36(总和)

    当我在 PBS 调度程序上运行 python 脚本 使用 Miniconda 时 出现标题中提到的错误 我认为 numpy 正在做一些多线程 处理 但我无法阻止它这样做 我将这些行添加到我的 PBS 脚本中 export MKL NUM T
  • 如何在 JAX-RS 中映射动态 JSON

    我必须使用 JAX RS Resteasy 作为实现 将 JSON 映射到 Java PoJos 问题是 JSON 是动态的 看这个例子 typeCode SAMPLE data id COMMENTS answerValue type Y
  • Ruby 的 Enumerator 对象如何在内部迭代器上进行外部迭代?

    根据 Ruby 的文档 Enumerator 对象使用each方法 枚举 如果没有提供目标方法to enum or enum for方法 现在 让我们以下面的猴子补丁及其枚举器为例 o Object new def o each yield