Hi,

At Mon, 17 Dec 2007 20:09:31 +0900,
Martin Duerst wrote in [ruby-core:14118]:
> However, it looks somewhat ugly and unnecessary, and it isn't compatible
> with 1.8. This could easily be fixed by adding uniq to Enumerator, the
> simplest form being:
>     def uniq
>       to_a.uniq
>     end

HTH.


Index: enum.c =================================================================== --- enum.c (revision 14281) +++ enum.c (working copy) @@ -1580,4 +1580,40 @@ enum_cycle(VALUE obj) } +static VALUE +uniq_all(VALUE i, VALUE p) +{ + VALUE *args = (VALUE *)p; + VALUE memo = args[0]; + + if (!RTEST(rb_hash_lookup(memo, i))) { + rb_hash_aset(memo, i, Qtrue); + rb_ary_push(args[1], i); + } + return Qnil; +} + +/* + * call-seq: + * enum.uniq -> an_array + * + * Returns a new array by removing duplicate values in <i>self</i>. + * + * a = [ "a", "a", "b", "b", "c" ] + * a.uniq #=> ["a", "b", "c"] + */ + +static VALUE +enum_uniq(VALUE obj) +{ + VALUE args[2]; + + args[0] = rb_hash_new(); + args[1] = rb_ary_new(); + + rb_block_call(obj, id_each, 0, 0, uniq_all, (VALUE)args); + + return args[1]; +} + /* * The <code>Enumerable</code> mixin provides collection classes with @@ -1635,4 +1671,5 @@ Init_Enumerable(void) rb_define_method(rb_mEnumerable, "drop_while", enum_drop_while, 0); rb_define_method(rb_mEnumerable, "cycle", enum_cycle, 0); + rb_define_method(rb_mEnumerable, "uniq", enum_uniq, 0); id_eqq = rb_intern("===");
-- Nobu Nakada