From 1289a7a11fe55a4e37d923fc6b0af2c228e83175 Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 23 Aug 2001 06:02:15 +0000 Subject: * eval.c (is_defined): should not dump core for "defined?(())". * eval.c (umethod_bind): recv can be an instance of descender of oklass if oklass is a Module. * hash.c (rb_hash_equal): check identiry equality first. * file.c (group_member): should check real gid only. * file.c (eaccess): do not cache euid, since effective euid may be changed via Process.euid=(). * file.c (eaccess): return -1 unless every specified access mode is permitted. * eval.c (rb_eval): while/until returns the value which is given to break. * parse.y (value_expr): using while/until/class/def as an expression is now gives a warning, not an error. * range.c (range_eqq): should compare strings based on magical increment (using String#upto), not dictionary order. * enum.c (enum_sort_by): new method for Schewartzian transformed stable sort. * variable.c (mod_av_set): detect constant overriding for built-in classes/modules. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1707 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- enum.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'enum.c') diff --git a/enum.c b/enum.c index 56d69502a0..d79178d393 100644 --- a/enum.c +++ b/enum.c @@ -203,6 +203,44 @@ enum_sort(obj) return rb_ary_sort(enum_to_a(obj)); } +static VALUE +sort_by_i(i, memo) + VALUE i; + NODE *memo; +{ + VALUE e = rb_ary_new3(3, rb_yield(e), INT2NUM(memo->u3.cnt), i); + rb_ary_push(memo->u1.value, e); + memo->u3.cnt++; + return Qnil; +} + +static VALUE +sort_by_sort_body(a) + VALUE a; +{ + return rb_ary_cmp(RARRAY(a)->ptr[0], RARRAY(a)->ptr[1]); +} + +static VALUE +enum_sort_by(obj) + VALUE obj; +{ + VALUE ary = rb_ary_new(); + NODE *memo = rb_node_newnode(NODE_MEMO, ary, 0, 0); + long i; + + rb_iterate(rb_each, obj, sort_by_i, (VALUE)memo); + rb_gc_force_recycle((VALUE)memo); + rb_iterate(rb_ary_sort_bang, ary, sort_by_sort_body, 0); + for (i=0; ilen; i++) { + VALUE e = RARRAY(ary)->ptr[i]; + RARRAY(ary)->ptr[i] = rb_ary_entry(e, 2); + rb_gc_force_recycle(e); + } + + return ary; +} + static VALUE all_i(i, memo) VALUE i; @@ -397,6 +435,7 @@ Init_Enumerable() rb_define_method(rb_mEnumerable,"entries", enum_to_a, 0); rb_define_method(rb_mEnumerable,"sort", enum_sort, 0); + rb_define_method(rb_mEnumerable,"sort_by", enum_sort_by, 0); rb_define_method(rb_mEnumerable,"grep", enum_grep, 1); rb_define_method(rb_mEnumerable,"find", enum_find, -1); rb_define_method(rb_mEnumerable,"detect", enum_find, -1); -- cgit v1.2.3