RCR: More enumerator functionality

Discussion in 'Ruby' started by Kristof Bastiaensen, May 17, 2004.

  1. Hi,
    I would like to know your opinion about the following idea's.
    (It is actually are two RCR's)

    (1)* Enumerable::filter and Enumerable::enum_filter

    filter([[method = :each], *args, ] block)
    yield values for which block returns true

    3.filter:)times, &lambda{ |i| i[0] == 0 }) do |n|
    puts "%i is even" % n
    end
    => 2 is even

    composers = %W(Brahms Berlioz Chopin)
    composers.filter(&lambda { |i| i[0] == ?B }) do |c|
    puts "composer with B: #{c}"
    end
    => composer with B: Brahms
    => composer with B: Berlioz

    and now the fun stuff (turning into an enum):

    5.enum_filter:)times){ |i| i[0] == 0 }.collect
    => [2, 4]

    (2)* Enumerable::Enumerator takes a optional block

    powers = 4.enum_for:)times){ |i| i * i }
    powers.collect
    => [0, 1, 4, 9]

    Thanks,
    Kristof
    Kristof Bastiaensen, May 17, 2004
    #1
    1. Advertising

  2. Kristof Bastiaensen

    Guest

    Hi,

    At Mon, 17 May 2004 20:34:05 +0900,
    Kristof Bastiaensen wrote in [ruby-talk:100500]:
    > filter([[method = :each], *args, ] block)
    > yield values for which block returns true
    >
    > 3.filter:)times, &lambda{ |i| i[0] == 0 }) do |n|
    > puts "%i is even" % n
    > end
    > => 2 is even


    $ ruby -c
    3.filter:)times, &lambda{ |i| i[0] == 0 }) do |n|
    puts "%i is even" % n
    end
    -:3: both block arg and actual block given

    > and now the fun stuff (turning into an enum):
    >
    > 5.enum_filter:)times){ |i| i[0] == 0 }.collect
    > => [2, 4]


    Is it a method of Enumerator, although Integer doesn't include
    it?

    > (2)* Enumerable::Enumerator takes a optional block
    >
    > powers = 4.enum_for:)times){ |i| i * i }
    > powers.collect
    > => [0, 1, 4, 9]


    Seems considerble, IMHO.

    --
    Nobu Nakada
    , May 17, 2004
    #2
    1. Advertising

  3. On Mon, 17 May 2004 21:46:45 +0900, nobu.nokada wrote:

    >> and now the fun stuff (turning into an enum):
    >>
    >> 5.enum_filter:)times){ |i| i[0] == 0 }.collect
    >> => [2, 4]

    >
    > Is it a method of Enumerator, although Integer doesn't include
    > it?


    Sorry, I forgot to mention it.
    It would be a method of Object (like enum_for).

    Regards,
    Kristof
    Kristof Bastiaensen, May 17, 2004
    #3
  4. il Mon, 17 May 2004 13:30:49 +0200, Kristof Bastiaensen
    <> ha scritto::

    >Hi,
    >I would like to know your opinion about the following idea's.
    >(It is actually are two RCR's)
    >
    >(1)* Enumerable::filter and Enumerable::enum_filter
    >
    >filter([[method = :each], *args, ] block)
    > yield values for which block returns true
    >
    >3.filter:)times, &lambda{ |i| i[0] == 0 }) do |n|
    > puts "%i is even" % n
    >end
    >=> 2 is even


    what's wrong with
    (1..3).select {|x| x[0]==0}.each {|x| p x}
    ?



    >
    >(2)* Enumerable::Enumerator takes a optional block
    >
    >powers = 4.enum_for:)times){ |i| i * i }
    >powers.collect
    >=> [0, 1, 4, 9]


    interesting, you should post this on rcrarchive (or maybe more than
    one)
    gabriele renzi, May 17, 2004
    #4
  5. "gabriele renzi" <> schrieb im Newsbeitrag
    news:...
    > il Mon, 17 May 2004 13:30:49 +0200, Kristof Bastiaensen
    > <> ha scritto::
    >
    > >Hi,
    > >I would like to know your opinion about the following idea's.
    > >(It is actually are two RCR's)
    > >
    > >(1)* Enumerable::filter and Enumerable::enum_filter
    > >
    > >filter([[method = :each], *args, ] block)
    > > yield values for which block returns true
    > >
    > >3.filter:)times, &lambda{ |i| i[0] == 0 }) do |n|
    > > puts "%i is even" % n
    > >end
    > >=> 2 is even

    >
    > what's wrong with
    > (1..3).select {|x| x[0]==0}.each {|x| p x}
    > ?


    If the Enumerable contains a huge number of elements then this version
    will burn a lot of memory while in certain cases (e.g. printing) it is
    more efficient to be able to handle one element at a time only.

    Well, of course in those cases you could simply do

    (1..3).each {|x| p x if x[0]==0}

    :)

    Regards

    robert
    Robert Klemme, May 17, 2004
    #5
  6. Hi,

    On Mon, 17 May 2004 15:55:25 +0200, Robert Klemme wrote:
    >>
    >> what's wrong with
    >> (1..3).select {|x| x[0]==0}.each {|x| p x}
    >> ?

    >
    > If the Enumerable contains a huge number of elements then this version
    > will burn a lot of memory while in certain cases (e.g. printing) it is
    > more efficient to be able to handle one element at a time only.
    >
    > Well, of course in those cases you could simply do
    >
    > (1..3).each {|x| p x if x[0]==0}
    >
    > :)
    >


    That's indeed more elegant than with filter and lambdas.
    The filter method would be only useful for implementing
    enum_filter, maybe I will exclude it from the RCR.

    Enum_filter would also behave like select, but it would
    be more efficient for memory. And you can keep the
    enumerable around it you need it later (even when the
    original object has changed it's contents).

    > Regards
    >
    > robert


    Thanks,
    Kristof
    Kristof Bastiaensen, May 17, 2004
    #6
  7. Hi --

    On Mon, 17 May 2004, Kristof Bastiaensen wrote:

    > 5.enum_filter:)times){ |i| i[0] == 0 }.collect
    > => [2, 4]


    [...]

    > (2)* Enumerable::Enumerator takes a optional block
    >
    > powers = 4.enum_for:)times){ |i| i * i }
    > powers.collect
    > => [0, 1, 4, 9]


    Keep in mind rejected RCR #50
    (http://www.rcrchive.net/rgarchive/rejected.html#rcr50). It's perhaps
    not identical to what you're proposing, but very similar. (It's
    proposed as a modification of #map.)

    (Aside: collect without a block returns an array with the same
    elements as the receiver, so there's probably no point calling it.)


    David

    --
    David A. Black
    David A. Black, May 18, 2004
    #7
  8. "David A. Black" <> schrieb im Newsbeitrag
    news:pine.LNX.4.44.0405181140170.1696-100000@wobblini...
    > Hi --
    >
    > On Mon, 17 May 2004, Kristof Bastiaensen wrote:
    >
    > > 5.enum_filter:)times){ |i| i[0] == 0 }.collect
    > > => [2, 4]

    >
    > [...]
    >
    > > (2)* Enumerable::Enumerator takes a optional block
    > >
    > > powers = 4.enum_for:)times){ |i| i * i }
    > > powers.collect
    > > => [0, 1, 4, 9]

    >
    > Keep in mind rejected RCR #50
    > (http://www.rcrchive.net/rgarchive/rejected.html#rcr50). It's perhaps
    > not identical to what you're proposing, but very similar. (It's
    > proposed as a modification of #map.)
    >
    > (Aside: collect without a block returns an array with the same
    > elements as the receiver, so there's probably no point calling it.)


    Probably #to_a would be clearer here. I guess the aim was to print an array
    from the Enumerator.

    robert
    Robert Klemme, May 18, 2004
    #8
  9. Hi --

    On Wed, 19 May 2004, Robert Klemme wrote:

    >
    > "David A. Black" <> schrieb im Newsbeitrag
    > news:pine.LNX.4.44.0405181140170.1696-100000@wobblini...
    > > Hi --
    > >
    > > On Mon, 17 May 2004, Kristof Bastiaensen wrote:
    > >
    > > > 5.enum_filter:)times){ |i| i[0] == 0 }.collect
    > > > => [2, 4]

    > >
    > > [...]
    > >
    > > > (2)* Enumerable::Enumerator takes a optional block
    > > >
    > > > powers = 4.enum_for:)times){ |i| i * i }
    > > > powers.collect
    > > > => [0, 1, 4, 9]

    > >
    > > Keep in mind rejected RCR #50
    > > (http://www.rcrchive.net/rgarchive/rejected.html#rcr50). It's perhaps
    > > not identical to what you're proposing, but very similar. (It's
    > > proposed as a modification of #map.)
    > >
    > > (Aside: collect without a block returns an array with the same
    > > elements as the receiver, so there's probably no point calling it.)

    >
    > Probably #to_a would be clearer here. I guess the aim was to print an array
    > from the Enumerator.


    Sorry; I was misreading the whole post, and therefore
    misunderstanding.


    David

    --
    David A. Black
    David A. Black, May 18, 2004
    #9
  10. Kristof Bastiaensen

    Guest

    Hi,

    At Mon, 17 May 2004 20:34:05 +0900,
    Kristof Bastiaensen wrote in [ruby-talk:100500]:
    > 5.enum_filter:)times){ |i| i[0] == 0 }.collect
    > => [2, 4]

    => [0, 2, 4]

    Isn't it?

    > (2)* Enumerable::Enumerator takes a optional block
    >
    > powers = 4.enum_for:)times){ |i| i * i }
    > powers.collect
    > => [0, 1, 4, 9]


    I tried the implementation of these two experimentally. But I
    feel enum_filter is overdoing after all.

    This patch provides block for Enumerable#enum_for and
    Enumerable#enum_if instead.

    $ ./ruby -renumerator -e 'p 5.enum_for:)times){|i| i*i}.to_a'
    [0, 1, 4, 9, 16]
    $ ./ruby -renumerator -e 'p 5.enum_for:)times).enum_if{|i| i[0] == 0}.to_a'
    [0, 2, 4]

    Just my 2 yens.


    Index: eval.c
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/eval.c,v
    retrieving revision 1.663
    diff -U2 -p -d -r1.663 eval.c
    --- eval.c 14 May 2004 16:45:21 -0000 1.663
    +++ eval.c 18 May 2004 01:02:30 -0000
    @@ -141,5 +141,5 @@ static VALUE rb_f_block_given_p _((void)
    static VALUE block_pass _((VALUE,NODE*));
    static VALUE rb_cMethod;
    -static VALUE method_call _((int, VALUE*, VALUE));
    +VALUE rb_method_call _((int, VALUE*, VALUE));
    static VALUE rb_cUnboundMethod;
    static VALUE umethod_bind _((VALUE, VALUE));
    @@ -8116,6 +8116,6 @@ proc_invoke(proc, args, self, klass)
    */

    -static VALUE
    -proc_call(proc, args)
    +VALUE
    +rb_proc_call(proc, args)
    VALUE proc, args; /* OK */
    {
    @@ -8606,5 +8606,5 @@ method_unbind(obj)
    */

    -static VALUE
    +VALUE
    rb_obj_method(obj, vid)
    VALUE obj;
    @@ -8686,6 +8686,6 @@ method_clone(self)
    */

    -static VALUE
    -method_call(argc, argv, method)
    +VALUE
    +rb_method_call(argc, argv, method)
    int argc;
    VALUE *argv;
    @@ -8981,5 +8981,5 @@ bmcall(args, method)

    a = svalue_to_avalue(args);
    - return method_call(RARRAY(a)->len, RARRAY(a)->ptr, method);
    + return rb_method_call(RARRAY(a)->len, RARRAY(a)->ptr, method);
    }

    @@ -9179,7 +9179,7 @@ Init_Proc()

    rb_define_method(rb_cProc, "clone", proc_clone, 0);
    - rb_define_method(rb_cProc, "call", proc_call, -2);
    + rb_define_method(rb_cProc, "call", rb_proc_call, -2);
    rb_define_method(rb_cProc, "arity", proc_arity, 0);
    - rb_define_method(rb_cProc, "[]", proc_call, -2);
    + rb_define_method(rb_cProc, "[]", rb_proc_call, -2);
    rb_define_method(rb_cProc, "==", proc_eq, 1);
    rb_define_method(rb_cProc, "eql?", proc_eq, 1);
    @@ -9199,6 +9199,6 @@ Init_Proc()
    rb_define_method(rb_cMethod, "hash", method_hash, 0);
    rb_define_method(rb_cMethod, "clone", method_clone, 0);
    - rb_define_method(rb_cMethod, "call", method_call, -1);
    - rb_define_method(rb_cMethod, "[]", method_call, -1);
    + rb_define_method(rb_cMethod, "call", rb_method_call, -1);
    + rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
    rb_define_method(rb_cMethod, "arity", method_arity, 0);
    rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
    Index: ext/enumerator/enumerator.c
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/ext/enumerator/enumerator.c,v
    retrieving revision 1.3
    diff -U2 -p -d -r1.3 enumerator.c
    --- ext/enumerator/enumerator.c 17 Oct 2003 14:09:43 -0000 1.3
    +++ ext/enumerator/enumerator.c 19 May 2004 02:40:29 -0000
    @@ -14,9 +14,70 @@

    #include "ruby.h"
    -#include "node.h"

    static VALUE rb_cEnumerator;
    static ID sym_each, sym_each_with_index, sym_each_slice, sym_each_cons;
    -static ID id_new, id_enum_obj, id_enum_method, id_enum_args;
    +#if !defined(HAVE_RB_PROC_CALL) || !defined(HAVE_RB_METHOD_CALL)
    +static ID id_call;
    +#endif
    +
    +static VALUE
    +proc_call(proc, args)
    + VALUE proc, args;
    +{
    +#ifdef HAVE_RB_PROC_CALL
    + if (TYPE(args) != T_ARRAY) {
    + args = rb_values_new(1, args);
    + }
    + return rb_proc_call(proc, args);
    +#else
    + return rb_funcall2(proc, id_call, 1, &args);
    +#endif
    +}
    +
    +static VALUE
    +method_call(method, args)
    + VALUE method, args;
    +{
    +#ifdef HAVE_RB_METHOD_CALL
    + return rb_method_call(RARRAY(args)->len, RARRAY(args)->ptr, method);
    +#else
    + return rb_funcall2(method, id_call, RARRAY(args)->len, RARRAY(args)->ptr);
    +#endif
    +}
    +
    +struct enumerator {
    + VALUE method;
    + VALUE proc;
    + VALUE args;
    + VALUE (*iter)_((VALUE, struct enumerator *));
    +};
    +
    +static void
    +enumerator_mark(ptr)
    + struct enumerator *ptr;
    +{
    + rb_gc_mark(ptr->method);
    + rb_gc_mark(ptr->proc);
    + rb_gc_mark(ptr->args);
    +}
    +
    +static struct enumerator *
    +enumerator_ptr(obj)
    + VALUE obj;
    +{
    + struct enumerator *ptr = DATA_PTR(obj);
    + if (!ptr) {
    + rb_raise(rb_eArgError, "uninitialized enumerator");
    + }
    + return ptr;
    +}
    +
    +static VALUE
    +enumerator_iter_i(i, e)
    + VALUE i;
    + struct enumerator *e;
    +{
    + return rb_yield(proc_call(e->proc, i));
    +}

    static VALUE
    @@ -26,5 +87,7 @@ obj_to_enum(obj, enum_args)
    rb_ary_unshift(enum_args, obj);

    - return rb_apply(rb_cEnumerator, id_new, enum_args);
    + return rb_class_new_instance(RARRAY(enum_args)->len,
    + RARRAY(enum_args)->ptr,
    + rb_cEnumerator);
    }

    @@ -33,14 +96,17 @@ enumerator_enum_with_index(obj)
    VALUE obj;
    {
    - return rb_funcall(rb_cEnumerator, id_new, 2, obj, sym_each_with_index);
    + VALUE args[2];
    + args[0] = obj;
    + args[1] = sym_each_with_index;
    + return rb_class_new_instance(2, args, rb_cEnumerator);
    }

    static VALUE
    -each_slice_i(val, memo)
    +each_slice_i(val, args)
    VALUE val;
    - NODE *memo;
    + VALUE *args;
    {
    - VALUE ary = memo->u1.value;
    - long size = memo->u3.cnt;
    + VALUE ary = args[0];
    + long size = (long)args[1];

    rb_ary_push(ary, val);
    @@ -48,5 +114,5 @@ each_slice_i(val, memo)
    if (RARRAY(ary)->len == size) {
    rb_yield(ary);
    - memo->u1.value = rb_ary_new2(size);
    + args[0] = rb_ary_new2(size);
    }

    @@ -59,17 +125,16 @@ enum_each_slice(obj, n)
    {
    long size = NUM2LONG(n);
    - NODE *memo;
    - VALUE ary;
    + VALUE args[2], ary;

    if (size <= 0) rb_raise(rb_eArgError, "invalid slice size");

    - memo = rb_node_newnode(NODE_MEMO, rb_ary_new2(size), 0, size);
    + args[0] = rb_ary_new2(size);
    + args[1] = (VALUE)size;

    - rb_iterate(rb_each, obj, each_slice_i, (VALUE)memo);
    + rb_iterate(rb_each, obj, each_slice_i, (VALUE)args);

    - ary = memo->u1.value;
    + ary = args[0];
    if (RARRAY(ary)->len > 0) rb_yield(ary);

    - rb_gc_force_recycle((VALUE)memo);
    return Qnil;
    }
    @@ -79,14 +144,18 @@ enumerator_enum_slice(obj, n)
    VALUE obj, n;
    {
    - return rb_funcall(rb_cEnumerator, id_new, 3, obj, sym_each_slice, n);
    + VALUE args[2];
    + args[0] = obj;
    + args[1] = sym_each_slice;
    + args[2] = n;
    + return rb_class_new_instance(3, args, rb_cEnumerator);
    }

    static VALUE
    -each_cons_i(val, memo)
    +each_cons_i(val, args)
    VALUE val;
    - NODE *memo;
    + VALUE *args;
    {
    - VALUE ary = memo->u1.value;
    - long size = memo->u3.cnt;
    + VALUE ary = args[0];
    + long size = (long)args[1];
    long len = RARRAY(ary)->len;

    @@ -107,13 +176,12 @@ enum_each_cons(obj, n)
    {
    long size = NUM2LONG(n);
    - NODE *memo;
    - VALUE ary;
    + VALUE args[3];

    if (size <= 0) rb_raise(rb_eArgError, "invalid size");
    - memo = rb_node_newnode(NODE_MEMO, rb_ary_new2(size), 0, size);
    + args[0] = rb_ary_new2(size);
    + args[1] = (VALUE)size;

    - rb_iterate(rb_each, obj, each_cons_i, (VALUE)memo);
    + rb_iterate(rb_each, obj, each_cons_i, (VALUE)args);

    - rb_gc_force_recycle((VALUE)memo);
    return Qnil;
    }
    @@ -123,5 +191,41 @@ enumerator_enum_cons(obj, n)
    VALUE obj, n;
    {
    - return rb_funcall(rb_cEnumerator, id_new, 3, obj, sym_each_cons, n);
    + VALUE args[2];
    + args[0] = obj;
    + args[1] = sym_each_cons;
    + args[2] = n;
    + return rb_class_new_instance(3, args, rb_cEnumerator);
    +}
    +
    +static VALUE
    +enumerator_select(i, e)
    + VALUE i;
    + struct enumerator *e;
    +{
    + if (!RTEST(proc_call(e->proc, i))) return Qnil;
    + return rb_yield(i);
    +}
    +
    +static VALUE
    +enumerator_enum_if(obj, enum_args)
    + VALUE obj, enum_args;
    +{
    + rb_ary_unshift(enum_args, obj);
    +
    + obj = rb_class_new_instance(RARRAY(enum_args)->len,
    + RARRAY(enum_args)->ptr,
    + rb_cEnumerator);
    + ((struct enumerator *)DATA_PTR(obj))->iter = enumerator_select;
    + return obj;
    +}
    +
    +static VALUE enumerator_allocate _((VALUE));
    +static VALUE
    +enumerator_allocate(klass)
    + VALUE klass;
    +{
    + struct enumerator *ptr;
    + return Data_Make_Struct(rb_cEnumerator, struct enumerator,
    + enumerator_mark, -1, ptr);
    }

    @@ -133,4 +237,5 @@ enumerator_initialize(argc, argv, obj)
    {
    VALUE enum_obj, enum_method, enum_args;
    + struct enumerator *ptr = enumerator_ptr(obj);

    rb_scan_args(argc, argv, "11*", &enum_obj, &enum_method, &enum_args);
    @@ -139,16 +244,25 @@ enumerator_initialize(argc, argv, obj)
    enum_method = sym_each;

    - rb_ivar_set(obj, id_enum_obj, enum_obj);
    - rb_ivar_set(obj, id_enum_method, enum_method);
    - rb_ivar_set(obj, id_enum_args, enum_args);
    + ptr->method = rb_obj_method(enum_obj, enum_method);
    + if (rb_block_given_p()) {
    + ptr->proc = rb_block_proc();
    + ptr->iter = enumerator_iter_i;
    + }
    + else {
    + ptr->iter = (VALUE (*)())rb_yield;
    + }
    + ptr->args = enum_args;

    - return Qnil;
    + return obj;
    }

    +static VALUE enumerator_iter _((VALUE));
    static VALUE
    -enumerator_iter(memo)
    - NODE *memo;
    +enumerator_iter(arg)
    + VALUE arg;
    {
    - return rb_apply(memo->u1.value, memo->u2.id, memo->u3.value);
    + struct enumerator *e = (struct enumerator *)arg;
    +
    + return method_call(e->method, e->args);
    }

    @@ -157,13 +271,16 @@ enumerator_each(obj)
    VALUE obj;
    {
    - VALUE val;
    + struct enumerator *e = enumerator_ptr(obj);

    - obj = (VALUE)rb_node_newnode(NODE_MEMO,
    - rb_ivar_get(obj, id_enum_obj),
    - rb_to_id(rb_ivar_get(obj, id_enum_method)),
    - rb_ivar_get(obj, id_enum_args));
    - val = rb_iterate((VALUE (*)_((VALUE)))enumerator_iter, obj, rb_yield, 0);
    - rb_gc_force_recycle(obj);
    - return val;
    + return rb_iterate(enumerator_iter, (VALUE)e, e->iter, (VALUE)e);
    +}
    +
    +static VALUE
    +enumerator_call(obj, args)
    + VALUE obj, args;
    +{
    + struct enumerator *e = enumerator_ptr(obj);
    +
    + return method_call(e->method, rb_ary_concat(e->args, args));
    }

    @@ -183,10 +300,13 @@ Init_enumerator()
    rb_define_method(rb_mEnumerable, "each_cons", enum_each_cons, 1);
    rb_define_method(rb_mEnumerable, "enum_cons", enumerator_enum_cons, 1);
    + rb_define_method(rb_mEnumerable, "enum_if", enumerator_enum_if, -2);

    rb_cEnumerator = rb_define_class_under(rb_mEnumerable, "Enumerator", rb_cObject);
    rb_include_module(rb_cEnumerator, rb_mEnumerable);

    + rb_define_alloc_func(rb_cEnumerator, enumerator_allocate);
    rb_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1);
    rb_define_method(rb_cEnumerator, "each", enumerator_each, 0);
    + rb_define_method(rb_cEnumerator, "call", enumerator_call, -2);

    sym_each = ID2SYM(rb_intern("each"));
    @@ -195,7 +315,6 @@ Init_enumerator()
    sym_each_cons = ID2SYM(rb_intern("each_cons"));

    - id_new = rb_intern("new");
    - id_enum_obj = rb_intern("enum_obj");
    - id_enum_method = rb_intern("enum_method");
    - id_enum_args = rb_intern("enum_args");
    +#if !defined(HAVE_RB_PROC_CALL) || !defined(HAVE_RB_METHOD_CALL)
    + id_call = rb_intern("call");
    +#endif
    }
    Index: ext/enumerator/extconf.rb
    ===================================================================
    RCS file: ext/enumerator/extconf.rb
    diff -N ext/enumerator/extconf.rb
    --- /dev/null 1 Jan 1970 00:00:00 -0000
    +++ ext/enumerator/extconf.rb 18 May 2004 11:50:10 -0000
    @@ -0,0 +1,5 @@
    +require 'mkmf'
    +
    +%w"rb_obj_method rb_method_call".all? {|f| have_func(f, "ruby.h")}
    +have_func("rb_proc_call", "ruby.h")
    +create_makefile("enumerator")


    --
    Nobu Nakada
    , May 19, 2004
    #10
  11. On Wed, 19 May 2004 11:47:30 +0900, nobu.nokada wrote:
    >> 5.enum_filter:)times){ |i| i[0] == 0 }.collect
    >> => [2, 4]

    > => [0, 2, 4]
    >
    > Isn't it?
    >


    Oh, yes, of course. (stupid mistake)

    >> (2)* Enumerable::Enumerator takes a optional block
    >>
    >> powers = 4.enum_for:)times){ |i| i * i }
    >> powers.collect
    >> => [0, 1, 4, 9]

    >
    > I tried the implementation of these two experimentally. But I
    > feel enum_filter is overdoing after all.
    >
    > This patch provides block for Enumerable#enum_for and
    > Enumerable#enum_if instead.


    Yes, that's cleaner. I like the naming also.

    >
    > $ ./ruby -renumerator -e 'p 5.enum_for:)times){|i| i*i}.to_a'
    > [0, 1, 4, 9, 16]
    > $ ./ruby -renumerator -e 'p 5.enum_for:)times).enum_if{|i| i[0] == 0}.to_a'
    > [0, 2, 4]
    >
    > Just my 2 yens.
    >

    Great!

    Thanks,
    Kristof
    Kristof Bastiaensen, May 19, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?SmltIEhlYXZleQ==?=

    Char Enumerator

    =?Utf-8?B?SmltIEhlYXZleQ==?=, Jul 16, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    390
    bruce barker
    Jul 16, 2004
  2. Angelos Karantzalis

    DataGrid: Bind to an Enumerator of object[]'s

    Angelos Karantzalis, Nov 4, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    447
  3. Thomas Hawtin
    Replies:
    7
    Views:
    392
    Roedy Green
    May 20, 2006
  4. Oliver Hopton

    Collection class bound to DataGrid doesn't use my custom enumerator!

    Oliver Hopton, Oct 1, 2003, in forum: ASP .Net Datagrid Control
    Replies:
    1
    Views:
    127
    Alan Green
    Oct 29, 2003
  5. Kristof Bastiaensen

    [RCR] More enumerator functionality

    Kristof Bastiaensen, Jun 17, 2004, in forum: Ruby
    Replies:
    8
    Views:
    123
    Kristof Bastiaensen
    Jun 19, 2004
Loading...

Share This Page