Bug #13648 ยป fix.patch
| enumerator.c | ||
|---|---|---|
| #define LAZY_MEMO_BREAK_P(memo) ((memo)->memo_flags & LAZY_MEMO_BREAK) | ||
| #define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED) | ||
| #define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK) | ||
| #define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value) | ||
| #define LAZY_MEMO_SET_VALUE(memo, value, packed) \ | ||
| ({ \ | ||
| MEMO_V2_SET(memo, value); \ | ||
| if (packed) (memo)->memo_flags |= LAZY_MEMO_PACKED; \ | ||
| else (memo)->memo_flags &= ~LAZY_MEMO_PACKED; \ | ||
| }) | ||
| static VALUE | ||
| lazy_init_yielder(VALUE val, VALUE m, int argc, VALUE *argv) | ||
| ... | ... | |
| lazy_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index) | ||
| { | ||
| VALUE value = lazyenum_yield_values(proc_entry, result); | ||
| LAZY_MEMO_SET_VALUE(result, value); | ||
| LAZY_MEMO_SET_VALUE(result, value, FALSE); | ||
| return result; | ||
| } | ||
| ... | ... | |
| if (!RTEST(chain)) return 0; | ||
| value = rb_proc_call_with_block(entry->proc, 1, &(result->memo_value), Qnil); | ||
| LAZY_MEMO_SET_VALUE(result, value); | ||
| LAZY_MEMO_SET_VALUE(result, value, FALSE); | ||
| return result; | ||
| } | ||
| test/ruby/test_lazy_enumerator.rb | ||
|---|---|---|
| def each(*args) | ||
| @args = args | ||
| @enum.each {|i| @current = i; yield i} | ||
| @enum.each do |v| | ||
| @current = v | ||
| if v.is_a? Enumerable | ||
| yield *v | ||
| else | ||
| yield v | ||
| end | ||
| end | ||
| end | ||
| end | ||
| ... | ... | |
| assert_equal(1, a.current) | ||
| end | ||
| def test_map_packed_nested | ||
| a = Step.new([[1, 2]]) | ||
| assert_equal([[[1, 2]]], a.lazy.map {|*args| args}.map {|*args| args}.to_a) | ||
| end | ||
| def test_flat_map | ||
| a = Step.new(1..3) | ||
| assert_equal(2, a.flat_map {|x| [x * 2]}.first) | ||