From: shugo@... Date: 2015-12-16T09:14:48+00:00 Subject: [ruby-core:72181] [Ruby trunk - Bug #11811] Chaining lazy enumerators causes duplicate ouput Issue #11811 has been updated by Shugo Maeda. Shugo Maeda wrote: > Nobuyoshi Nakada wrote: > > I'm afraid that it may cause GC mark miss of dynamic symbols. > > Ah, I see. > > How about to apply the optimization only to static symbols? Or the following patch also seems to fix the bug: ``` diff --git a/vm.c b/vm.c index 087cba7..a03e068 100644 --- a/vm.c +++ b/vm.c @@ -567,6 +567,10 @@ vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block, VALUE *procptr) *procptr = block->proc = rb_vm_make_proc(th, block, rb_cProc); return TRUE; } + else if (SYMBOL_P(block->proc)) { + *procptr = rb_sym_to_proc(block->proc); + return TRUE; + } else { *procptr = block->proc; return FALSE; ``` ---------------------------------------- Bug #11811: Chaining lazy enumerators causes duplicate ouput https://bugs.ruby-lang.org/issues/11811#change-55595 * Author: Chris Beer * Status: Open * Priority: Normal * Assignee: Nobuyoshi Nakada * ruby -v: ruby 2.3.0preview2 (2015-12-11 trunk 53028) [x86_64-darwin15] * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- In Ruby 2.3.0-preview2, I'm seeing a change in behavior using lazy enumerators with select/reject and the & operator: irb(main):037:0> %w(1 2 3).lazy.reject(&:empty?).each { |x| puts x } 1 1 2 2 3 3 Note that the output is doubled. However, if I don't use the & shorthand, the output is as expected: irb(main):038:0> %w(1 2 3).lazy.reject { |x| x.empty? }.each { |x| puts x } 1 2 3 => nil And in Ruby 2.2.3, both variants produced the same result: irb(main):001:0> %w(1 2 3).lazy.reject(&:empty?).each { |x| puts x } 1 2 3 => nil ---Files-------------------------------- vm_caller_setup_arg_block.diff (1.03 KB) -- https://bugs.ruby-lang.org/