当您的类未定义 #each 时,返回 Enumerator::Lazy 的最佳方法是什么?

2023-11-23

Enumerable#lazy依赖于你的枚举提供#each方法。如果你的枚举没有#each你不能使用的方法#lazy. Now Kernel#enum_for and #to_enum提供指定枚举方法以外的灵活性#each:

Kernel#enum_for(method = :each, *args)

But #enum_for朋友们总是构造简单的(非惰性的)枚举器,从不Enumerator::Lazy.

我看到Enumerator在 Ruby 1.9.3 中提供了类似形式的#new:

Enumerator#new(obj, method = :each, *args)

不幸的是,该构造函数在 Ruby 2.0 中已被完全删除。而且我认为它根本不可用Enumerator::Lazy。所以在我看来,如果我有一个带有方法的类,我想为其返回一个惰性枚举器,如果该类没有#each然后我必须定义一些帮助器类来定义#each.

例如,我有一个Calendar班级。对我来说,提供从所有时间开始枚举每个日期并没有真正的意义。一个#each就没用了。相反,我提供了一种从开始日期开始(惰性地)枚举的方法:

  class Calendar
    ...
    def each_from(first)
      if block_given?
        loop do
          yield first if include?(first)
          first += step
        end
      else
        EachFrom.new(self, first).lazy
      end
    end
  end

然后EachFrom类看起来像这样:

class EachFrom
  include Enumerable
  def initialize(cal, first)
    @cal   = cal
    @first = first
  end
  def each
    @cal.each_from(@first) do |yielder, *vals|
      yield yielder, *vals
    end
  end
end

它有效,但感觉很重。也许我应该子类化Enumerator::Lazy并定义一个类似于已弃用的构造函数Enumerator。你怎么认为?


我认为你应该恢复正常Enumerator using to_enum:

class Calendar
  # ...
  def each_from(first)
    return to_enum(:each_from, first) unless block_given?
    loop do
      yield first if include?(first)
      first += step
    end
  end
end

这是大多数红宝石爱好者所期望的。尽管它是无限的Enumerable,还是可以用的,例如:

Calendar.new.each_from(1.year.from_now).first(10) # => [...first ten dates...]

如果他们确实需要一个惰性枚举器,他们可以调用lazy他们自己:

Calendar.new.each_from(1.year.from_now)
  .lazy
  .map{...}
  .take_while{...}

If you really想要返回一个惰性枚举器,你可以调用lazy从你的方法:

  # ...
  def each_from(first)
    return to_enum(:each_from, first).lazy unless block_given?
    #...

但我不会推荐它,因为它会是意想不到的(IMO),可能是一种矫枉过正并且性能会降低。

最后,你的问题有几个误解:

  • 所有方法Enumerable假设一个each, 不只是lazy.

  • 您可以定义一个each如果您愿意并包含需要参数的方法Enumerable。大多数方法Enumerable行不通,但是each_with_index其他一些人将转发参数,以便这些参数可以立即使用。

  • The Enumerator.new没有块就消失了,因为to_enum是人们应该使用的。请注意,块形式仍然存在。还有一个构造函数Lazy,但这意味着从现有的Enumerable.

  • 你说to_enum从不创建惰性枚举器,但这并不完全正确。Enumerator::Lazy#to_enum专门返回一个惰性枚举器。任何用户方法Enumerable那个叫to_enum将使惰性枚举器保持惰性。

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

当您的类未定义 #each 时,返回 Enumerator::Lazy 的最佳方法是什么? 的相关文章

随机推荐

  • 在 R 中抓取受密码保护的网站

    我正在尝试从 R 中受密码保护的网站中抓取数据 通过阅读 httr 和 RCurl 包似乎是使用密码身份验证进行抓取的最佳选择 我还研究了 XML 包 我试图抓取的网站如下 您需要一个免费帐户才能访问完整页面 http subscriber
  • 使用 Visual Studio 2010 运行 64 位版本的 IIS Express 8 RC

    我有一个使用 64 位版本的网络应用程序SharpSvn 具有非托管依赖项的托管 DLL 它不能在 IIS Express 7 0 中运行 切换到 32 位版本的程序集效果很好 我安装的是64位版本IIS 8 RC 但是 Visual St
  • 为什么这不能在 Java 中编译?

    如果你给 public class test public static void main String ar if true int i 0 它没有编译 但带大括号的相同代码是 public class test public stat
  • 为笔记本设置默认 sys.path

    我将所有 py 文件放在文件夹 script 中 将所有 IPython 笔记本放在名为 Notebook 的文件夹下 每个笔记本文件对脚本上的一个或多个文件存在多个交叉依赖关系 Having sys path append在每个笔记本顶部
  • Sails.JS HTTP + HTTPS

    我正在尝试弄清楚如何提升一个同时响应 HTTP 和 HTTPS 请求的 sails 应用程序 我使用了 config local js 方法来配置express 如下 详细here var fs require fs module expo
  • 警报对话框中 EditText 框的空验证 - Android

    我正在尝试向位于警报对话框内的编辑文本字段添加一些文本验证 它提示用户输入名称 我想添加一些验证 这样如果他们输入的内容为空或为空 除了创建一个显示错误的 Toast 之外 它不会执行任何操作 到目前为止我有 AlertDialog Bui
  • IoC、Dll 引用和程序集扫描

    虽然这个问题与 StructureMap 有关 但我的一般问题是 使用 IoC 连接组件时 容器in code 相反 通过配置xml 你 通常需要明确的项目 构建 对所有程序集的引用 为什么要使用单独的组件 因为 抽象类驻留在 将组件与混凝
  • W/ViewRootImpl:由于没有窗口焦点而取消事件:MotionEvent?

    每次我从子活动按回父活动时都会收到此错误 W ViewRootImpl Cancelling event due to no window focus MotionEvent action ACTION CANCEL actionButto
  • 如何在 CouchDB 中使用 Map-Reduce 计算最大值?

    我知道有内置的 stats提供 sum count min max 和 sumsqr 的函数 我想知道的是如何以映射缩减方式计算最大值 如果没有更多信息 我无法想出一个可以工作的归约函数 我唯一能想到的就是对值进行排序并选取第一个值 我的地
  • 如何对单个 Neo4j 数据库进行分区?

    是否可以将一个 Neo4j 数据库进行划分 使一个数据库中有多个起点 从而可以隔离所有查询 而不是拥有多个数据库 我已经考虑过这一点 并且我认为它在一定程度上可以发挥作用 但是一旦使用了标签之类的东西 那么这个想法就行不通了 因为标签查询将
  • 在 jenkins 的 github pull request 中添加评论

    我在 Jenkins 中使用 Git 拉取请求构建器插件将拉取请求链接到 Jenkins 作业由钩子触发 一切运行顺利 尽管如此 在构建结束时 我想在出现失败 成功或错误时添加注释 我尝试使用管道并使用 pullRequest commen
  • AsyncUdpSocket如何使用接收

    我正在尝试让 iPhone 的程序在模拟器上运行 我的问题是接收 UDP 数据 我使用异步 Udp 套接字 如果我制作一个套接字并使用sendData NSData toHost 效果很好 我想我无法弄清楚接收功能是如何工作的 我假设是这样
  • MySQL、json、JSON_ARRAY_APPEND - 为什么追加在 5.7.13 上不起作用?

    我到底如何将数据插入 json mysql 字段 我可以创造一个记录 INSERT INTO git object user id git meta last update VALUES 11111 host a id 1 select n
  • instagram api 中的回调 url 是什么以及如何实现它

    嗨 我是初学者程序员 我正在尝试使用 Instagram 的实时照片更新 api 我的目的是使用这个API CONSOLE的订阅方法 https apigee com console instagram 但我无法理解和处理回调 url 回调
  • 具有离线路线功能的离线 iPhone 地图 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我正在开发一个 iPhon
  • 如何传递日期时间参数?

    如何将 UTC 日期传递给 Web API Passing 2010 01 01工作正常 但是当我传递 UTC 日期时 例如2014 12 31T22 00 00 000Z 带有时间部分 我收到 HTTP 404 响应 所以 http do
  • 防止 ASP.Net MVC 中的 Cookie 重放攻击

    我的任务是实现本文中的第 4 点 http support microsoft com kb 900111 这涉及使用会员资格提供程序在用户登录和注销时向服务器端记录添加注释 然后确认当使用 cookie 进行身份验证时 用户尚未注销 这对
  • 按字母顺序粘贴两个向量的元素

    假设我有两个向量 a lt c george harry harry chris steve steve steve harry b lt c harry steve chris harry harry george chris georg
  • 将 GNU 大小写范围扩展转换为标准 C

    GNU 大小写范围扩展允许 switch 语句中的大小写范围 switch value case 1 8 printf Hello 1 to 8 n break default printf Hello default n break 如何
  • 当您的类未定义 #each 时,返回 Enumerator::Lazy 的最佳方法是什么?

    Enumerable lazy依赖于你的枚举提供 each方法 如果你的枚举没有 each你不能使用的方法 lazy Now Kernel enum for and to enum提供指定枚举方法以外的灵活性 each Kernel enu