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
。你怎么认为?