【发布时间】:2013-04-04 09:30:18
【问题描述】:
Enumerable#lazy 依赖于您的可枚举提供 #each 方法。如果你的枚举没有#each 方法,你就不能使用#lazy。现在Kernel#enum_for 和#to_enum 提供了指定#each 以外的枚举方法的灵活性:
Kernel#enum_for(method = :each, *args)
但是#enum_for 和朋友们总是构造普通的(非惰性的)枚举器,而不是Enumerator::Lazy。
我看到 Ruby 1.9.3 中的 Enumerator 提供了这种类似的 #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 中已弃用的构造函数。你怎么看?
【问题讨论】:
标签: ruby lazy-evaluation enumerable ruby-2.0