如何生成一个proc来返回哈希中的连续条目,进行转换?

时间:2016-09-02 19:59:06

标签: ruby

我想生成一个proc,当被调用时,返回任何Enumerable的连续值。换句话说:

a_proc = generate_proc([:a, :b, :c])
a_proc.call # => :a
a_proc.call # => :b

理想情况下,我也希望在返回之前对其进行翻译,因此它可能会被用作:

a_proc = generate_proc([:a, :b, :c ]) { |e| "Element: #{e.inspect}" }
a_proc.call # => "Element: :a"
a_proc.call # => "Element: :b"
a_proc.call # => "Element: :c"

3 个答案:

答案 0 :(得分:4)

这并不是您要求的,但我认为它可能符合您的需求:

an_enum = [:a, :b, :c].each

an_enum.next # => :a
an_enum.next # => :b

an_enum = [:a, :b, :c].map { |e| "Element: #{e.inspect}" }.each
# or, if you want to defer calling the block...
an_enum = [:a, :b, :c].lazy.map { |e| "Element: #{e.inspect}" }

an_enum.next # => "Element: :a"
an_enum.next # => "Element: :b"
an_enum.next # => "Element: :c"

有关详细信息,请查看EnumeratorEnumerator::Lazy

更新来自未来,更智能,更耐心的我:

要回答原始问题,可以使用Object#method将任何对象的方法转换为绑定的可调用对象。我们甚至可以Enumerator#next

an_enum = [:a, :b, :c].each
a_proc = an_enum.method(:next)

a_proc.call # => :a
a_proc.call # => :b
a_proc.call # => :c

答案 1 :(得分:1)

def generate_proc x, &postproc
  myobj = Fiber.new { x.each { |v| Fiber.yield v }}

  postproc ? -> () { postproc.call myobj.resume } :
             -> () {               myobj.resume }
end

答案 2 :(得分:0)

这正是你所要求的:

def generate_proc(list, &transform)
  enum = list.to_enum
  if transform
    proc { transform[enum.next] }
  else
    proc { enum.next }
  end
end