Ruby 1.9.1 中的枚举器如何工作?

2024-02-23

这个问题不是关于如何在 Ruby 1.9.1 中使用枚举器,而是我很好奇它们是如何工作的。这是一些代码:

class Bunk
  def initialize
    @h = [*1..100]
  end

  def each
    if !block_given?
      enum_for(:each)
    else
      0.upto(@h.length) { |i|
        yield @h[i]
      }
    end
  end
end

在上面的代码中我可以使用e = Bunk.new.each, 进而e.next, e.next获取每个连续的元素,但它到底是如何暂停执行然后在正确的位置恢复的呢?

我知道如果产量0.upto被替换为Fiber.yield那么就很容易理解了,但是这里不是这样的。这是一个普通的旧yield, 那么它是怎样工作的?

我查看了 enumerator.c 但它对我来说几乎无法理解。也许有人可以在 Ruby 中提供一个实现,使用纤程,而不是 1.8.6 风格的基于连续的枚举器,这样一切就清楚了?


这是一个使用 Fibers 的普通 ruby​​ 枚举器,其行为应该与原始枚举器非常相似:

class MyEnumerator
  include Enumerable

  def initialize(obj, iterator_method)
    @f = Fiber.new do
      obj.send(iterator_method) do |*args|
        Fiber.yield(*args)
      end
      raise StopIteration
    end
  end

  def next
    @f.resume
  end

  def each
    loop do
      yield self.next
    end
  rescue StopIteration
    self
  end
end

如果有人对使用异常进行控制流感到不安:真正的枚举器也会在最后引发 StopIteration,所以我只是模拟原始行为。

Usage:

>> enum = MyEnumerator.new([1,2,3,4], :each_with_index)
=> #<MyEnumerator:0x9d184f0 @f=#<Fiber:0x9d184dc>
>> enum.next
=> [1, 0]
>> enum.next
=> [2, 1]
>> enum.to_a
=> [[3, 2], [4, 3]]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby 1.9.1 中的枚举器如何工作? 的相关文章

  • 迁移后删除轨道模型

    我觉得很奇怪 创建模型 运行迁移 销毁它 然后再次创建相同的模型会报告 SQL 异常 project master rails g model name name invoke active record create db migrate
  • 以与版本页面上相同的方式区分两个字符串的算法是什么?

    我正在尝试按短语区分两个字符串 类似于 StackOverflow 在版本编辑页面上区分两个字符串的方式 执行此操作的算法是什么 是否有 gems 或其他标准库可以实现此目的 编辑 我见过其他比较算法 Differ http github
  • 是否有用于序列化和反序列化各种格式的对象层次结构的模式?

    给定一个复杂的对象层次结构 幸运的是它不包含循环引用 如何实现支持各种格式的序列化 我不是来讨论实际实施的 相反 我正在寻找可能派上用场的设计模式的提示 更准确地说 我正在使用 Ruby 我想解析 XML 和 JSON 数据以构建复杂的对象
  • Gem .gemspec 中的本地依赖关系

    我正在开发一个 gem Gem A 它使用了我也编写的另一个 gem Gem B 到目前为止 Gem B 已添加到 Gem A 的 gemspec 中 gem add dependency gem a gt 0 0 4 但我现在发现需要使用
  • 在 Rails 控制台中创建实例时,Rails 4 强参数失败

    可能在这里做了一些愚蠢的事情 但这是我的基本千篇一律的课程 class League lt ActiveRecord Base private def league params params require full name permi
  • 如何在 Ruby 中获取网页的 HTML 源代码 [重复]

    这个问题在这里已经有答案了 在 Firefox 或 Safari 等浏览器中 打开网站后 我可以右键单击该页面 然后选择以下内容 查看页面源代码 或 查看源代码 这显示了该页面的 HTML 源代码 在 Ruby 中 是否有一个函数 也许是一
  • 如何随机生成文件的链接?

    我有一个 PDF 文件 我不想通过我网站上的 URL 公开访问该文件 作为 轻微 安全层 我想通过电子邮件向用户发送一个唯一的 随机生成的 URL 他们可以从中下载 PDF 我将把该 PDF 存储在 AWS 或类似的地方 我感觉自己被困在r
  • 如何根据多对多相关模型的属性查找记录?

    楷模 InternalUser has many internal user roles has many roles through gt internal user roles InternalUserRole belongs to i
  • 在 Ruby 中创建 Microsoft Word (.docx) 文档

    有没有一种简单的方法可以在 Ruby 应用程序中创建 Word 文档 docx 实际上 就我而言 它是一个由 Linux 服务器提供服务的 Rails 应用程序 类似的宝石Prawn http prawn majesticseacreatu
  • 在类中调用类方法

    我意识到这可能是一个幼稚的问题 但我仍然无法弄清楚如何在 Ruby 类中从另一个方法调用一个方法 即在 Ruby 中可以执行以下操作 class A def met1 end def met2 met1 call to previously
  • 单表继承发现问题

    我有以下3个rails类 它们都存储在一张表中 使用rails的单表继承 class Template lt ActiveRecord Base class ThingTemplate lt Template class StockThin
  • Rails 3 ActiveAdmin。如何为关联记录设置默认排序顺序?

    我有一个发货模型和一个发票模型 发票属于装运 所以我添加了一个默认的发货排序顺序 如下所示 config sort order file number desc 但现在我想为发票添加相同的排序顺序 发货表是具有 file number 列的
  • 使用 Assetic PHP 通过 RVM 安装后 Sass 损坏

    我正在尝试设置 Assetic PHP 资源编译器 并且它可以与 CoffeeScript Stylus 和 Less 一起使用 所有 NPM 包都运行良好 然而 对于 Sass 我遇到了问题 以下是我到目前为止所采取的步骤 我安装了 RV
  • Rails 和 Mysql 的毫秒数

    使用 Rails Mysql 时存储时间 以毫秒为单位 的最佳方式是什么 我将使用小数和composed of 以便能够将该值作为Ruby 时间进行操作 有人有更好的主意吗 自从提出这个问题以来 已经过去了好几年了 这是更新的解决方案 ht
  • 如何让我的导航栏出现在 Rails 应用程序的每个页面上?

    目前 我的导航栏位于我的index htm erb 文件中 目前仅在主页上显示 我想知道为了让导航栏出现在我的应用程序的每一页上 必须采取哪些必要步骤 我的导航栏的代码如下所示
  • 为什么我在安装 Rails 时会出现“写权限”错误?

    当我使用rvm use 1 9 2 我得到 Rails v3 0 0 vikas admin1 DL H61MXEL rvm use 1 9 2 default Using home vikas rvm gems ruby 1 9 2 p3
  • FieldPath 字段名称不能包含“.”当尝试使用 AGGREGATE 时

    我的查询有什么问题吗 db table aggregate match gt expr gt and gt eq gt size gt events 4 events 0 updated gt lt gt 2019 05 05 我越来越 M
  • 处理中渲染极地带面体时出现问题

    我最近一直在研究 Zohedrons 和Rob Bell http zomadic com 做出了美丽的 我玩了免费的极地带面体 Sketchup 插件 http zomebuilder com 并考虑使用几何图形加工 http proce
  • RSpec 抛出分段错误

    有时我的测试套件会无缘无故地抛出分段错误 这是输出 Users Test rvm gems ruby 1 9 3 p392 gems activerecord 3 2 9 lib active record relation query m
  • Rails-自定义删除前确认对话框的视图

    要删除 Rails 中的记录 我使用此代码 result of which I get dialog box like this But I wants this dialog box to look like this 有没有办法自定义确

随机推荐