从
docs for Ruby v2.5
e = [1,2,3].map p e.next #=> 1 e.Feed "a" p e.next #=> 2 e.Feed "b" p e.next #=> 3 e.Feed "c" begin e.next rescue stopiteration p $!.result #=> ["a","b","c"] end
但是当我通过Enumerator.new创建枚举时呢?
# a naive rework of the above enum e2 = Enumerator.new do |y| [1,3].each do |x| y << x end # raise stopiteration,FED # <= how to get `FED`? end p e2.next #=> 1 e2.Feed "a" p e2.next #=> 2 e2.Feed "b" p e2.next #=> 3 e2.Feed "c" begin e2.next rescue stopiteration p $!.result #=> nil end
我如何修改它以匹配API?
我尝试过的事情:
e2 = Enumerator.new do |y| [1,3].each do |x| @fed = yield y << x end raise stopiteration,@fed end e2 = Enumerator.new do |y| [1,3].each do |x| y << yield(x) end raise stopiteration,y end e2 = Enumerator.new do |y| enum = [1,3].each{|x| yield x }.to_enum y << enum.next raise stopiteration,y end
# Ignoring all the other errors that jump up… p e2.next #=> 1 e2.Feed "a" # nil p e2.next #=> 2 e2.Feed "b"
TypeError: Feed value already set
TypeError:已设置的Feed值意味着它正在某处收集值,我只是不知道如何访问它.
static VALUE enumerator_Feed(VALUE obj,VALUE v) { struct enumerator *e = enumerator_ptr(obj); if (e->Feedvalue != Qundef) { rb_raise(rb_eTypeError,"Feed value already set"); } e->Feedvalue = v; return Qnil; }
所以Feedvalue是我的目标.我已经使用Pry进入了该方法的操作,但找不到与Feed或Feedvalue相关的方法或变量. Rubinius makes this available explicitly(至少作为实例变量).
我很难过.
任何帮助或见解将不胜感激.
解决方法
你的第一个例子是枚举数,其yield方法为:map:
e = [1,3].map => #<Enumerator: [1,3]:map>
e2 = Enumerator.new do |y| [1,FED # <= how to get `FED`? end => #<Enumerator: #<Enumerator::Generator:0x007fa69b056b50>:each>
您应该使用to_enum或enum_for以及您选择的yield方法:
[1,3].to_enum(:map) => #<Enumerator: [1,3]:map>
以下方式使用:: new现在已弃用,因此我不建议使用它来支持提供相同功能的to_enum或enum_for:
Enumerator.new([1,3],:map)
总结一下,#map是第一个迭代器调用的方法,当它是called时,它的return values将决定结果的值.当像其他例子一样使用#each时,你的块(#Feed)结束并不重要,因为它不会影响#each的返回值.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。