diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-08-23 06:02:15 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-08-23 06:02:15 +0000 |
commit | 1289a7a11fe55a4e37d923fc6b0af2c228e83175 (patch) | |
tree | fe8a90542f77c78ecdaef684d155c6ea66a7dcef /enum.c | |
parent | e15efe7733f5e6e9377ae1bd2fc5f6029c919f1d (diff) | |
download | ruby-1289a7a11fe55a4e37d923fc6b0af2c228e83175.tar.gz |
* 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
Diffstat (limited to 'enum.c')
-rw-r--r-- | enum.c | 39 |
1 files changed, 39 insertions, 0 deletions
@@ -204,6 +204,44 @@ enum_sort(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; i<RARRAY(ary)->len; 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; NODE *memo; @@ -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); |