summaryrefslogtreecommitdiff
path: root/enum.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-08-23 06:02:15 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-08-23 06:02:15 +0000
commit1289a7a11fe55a4e37d923fc6b0af2c228e83175 (patch)
treefe8a90542f77c78ecdaef684d155c6ea66a7dcef /enum.c
parente15efe7733f5e6e9377ae1bd2fc5f6029c919f1d (diff)
downloadruby-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.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/enum.c b/enum.c
index 56d69502a0..d79178d393 100644
--- a/enum.c
+++ b/enum.c
@@ -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);