[macruby-changes] [4078] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue May 11 19:14:52 PDT 2010
Revision: 4078
http://trac.macosforge.org/projects/ruby/changeset/4078
Author: martinlagardette at apple.com
Date: 2010-05-11 19:14:49 -0700 (Tue, 11 May 2010)
Log Message:
-----------
Improve core/enumerator pass rate
- Implement `#each_with_object`, `#with_object`
- Backport changes to `#each_with_index` and `#with_index`
Modified Paths:
--------------
MacRuby/trunk/enumerator.c
Removed Paths:
-------------
MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/each_with_object_tags.txt
MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_index_tags.txt
MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_object_tags.txt
Modified: MacRuby/trunk/enumerator.c
===================================================================
--- MacRuby/trunk/enumerator.c 2010-05-12 02:07:24 UTC (rev 4077)
+++ MacRuby/trunk/enumerator.c 2010-05-12 02:14:49 UTC (rev 4078)
@@ -300,66 +300,118 @@
argc, argv);
}
-/*
- * call-seq:
- * enum.each {...}
- *
- * Iterates the given block using the object and the method specified
- * in the first place. If no block is given, returns self.
- *
- */
static VALUE
-enumerator_each(VALUE obj, SEL sel)
+enumerator_block_call(VALUE obj, VALUE (*func)(ANYARGS), VALUE arg)
{
struct enumerator *e;
int argc = 0;
const VALUE *argv = 0;
- if (!rb_block_given_p()) return obj;
e = enumerator_ptr(obj);
if (e->args != 0) {
argc = RARRAY_LEN(e->args);
argv = RARRAY_PTR(e->args);
}
return rb_objc_block_call(e->obj, e->sel, NULL, argc, (VALUE *)argv,
- enumerator_each_i, (VALUE)e);
+ func, arg);
}
+/*
+ * call-seq:
+ * enum.each {...}
+ *
+ * Iterates the given block using the object and the method specified
+ * in the first place. If no block is given, returns self.
+ *
+ */
static VALUE
-enumerator_with_index_i(VALUE val, VALUE *memo)
+enumerator_each(VALUE obj, SEL sel)
{
- val = rb_yield_values(2, val, INT2FIX(*memo));
+ if (!rb_block_given_p()) {
+ return obj;
+ }
+ return enumerator_block_call(obj, enumerator_each_i, obj);
+}
+
+static VALUE
+enumerator_with_index_i(VALUE val, VALUE m, int argc, VALUE *argv)
+{
+ VALUE idx;
+ VALUE *memo = (VALUE *)m;
+
+ idx = INT2FIX(*memo);
++*memo;
- return val;
+
+ if (argc <= 1)
+ return rb_yield_values(2, val, idx);
+
+ return rb_yield_values(2, rb_ary_new4(argc, argv), idx);
}
/*
* call-seq:
- * e.with_index {|(*args), idx| ... }
+ * e.with_index(offset = 0) {|(*args), idx| ... }
* e.with_index
*
* Iterates the given block for each elements with an index, which
- * start from 0. If no block is given, returns an enumerator.
+ * starts from +offset+. If no block is given, returns an enumerator.
*
*/
static VALUE
-enumerator_with_index(VALUE obj, SEL sel)
+enumerator_with_index(VALUE obj, SEL sel, int argc, VALUE *argv)
{
- struct enumerator *e;
- VALUE memo = 0;
- int argc = 0;
- const VALUE *argv = 0;
+ VALUE memo;
- RETURN_ENUMERATOR(obj, 0, 0);
- e = enumerator_ptr(obj);
- if (e->args != 0) {
- argc = RARRAY_LEN(e->args);
- argv = RARRAY_PTR(e->args);
+ rb_scan_args(argc, argv, "01", &memo);
+ RETURN_ENUMERATOR(obj, argc, argv);
+ memo = NIL_P(memo) ? 0 : (VALUE)NUM2LONG(memo);
+ return enumerator_block_call(obj, enumerator_with_index_i, (VALUE)&memo);
+}
+
+/*
+ * call-seq:
+ * e.each_with_index {|(*args), idx| ... }
+ * e.each_with_index
+ *
+ * Same as Enumeartor#with_index, except each_with_index does not
+ * receive an offset argument.
+ *
+ */
+static VALUE
+enumerator_each_with_index(VALUE obj, SEL sel)
+{
+ return enumerator_with_index(obj, sel, 0, NULL);
+}
+
+static VALUE
+enumerator_with_object_i(VALUE val, VALUE memo, int argc, VALUE *argv)
+{
+ if (argc <= 1) {
+ return rb_yield_values(2, val, memo);
}
- return rb_objc_block_call(e->obj, e->sel, NULL, argc, (VALUE *)argv,
- enumerator_with_index_i, (VALUE)&memo);
+
+ return rb_yield_values(2, rb_ary_new4(argc, argv), memo);
}
+/*
+ * call-seq:
+ * e.with_object(obj) {|(*args), memo_obj| ... }
+ * e.with_object(obj)
+ *
+ * Iterates the given block for each element with an arbitrary
+ * object given, and returns the initially given object.
+ *
+ * If no block is given, returns an enumerator.
+ *
+ */
+static VALUE
+enumerator_with_object(VALUE obj, SEL sel, VALUE memo)
+{
+ RETURN_ENUMERATOR(obj, 1, &memo);
+ enumerator_block_call(obj, enumerator_with_object_i, memo);
+ return memo;
+}
+
#if 0
static VALUE
next_ii(VALUE i, VALUE obj, int argc, VALUE *argv)
@@ -461,8 +513,10 @@
rb_objc_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1);
rb_objc_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
rb_objc_define_method(rb_cEnumerator, "each", enumerator_each, 0);
- rb_objc_define_method(rb_cEnumerator, "each_with_index", enumerator_with_index, 0);
- rb_objc_define_method(rb_cEnumerator, "with_index", enumerator_with_index, 0);
+ rb_objc_define_method(rb_cEnumerator, "each_with_index", enumerator_each_with_index, 0);
+ rb_objc_define_method(rb_cEnumerator, "each_with_object", enumerator_with_object, 1);
+ rb_objc_define_method(rb_cEnumerator, "with_index", enumerator_with_index, -1);
+ rb_objc_define_method(rb_cEnumerator, "with_object", enumerator_with_object, 1);
rb_objc_define_method(rb_cEnumerator, "next", enumerator_next, 0);
rb_objc_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/each_with_object_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/each_with_object_tags.txt 2010-05-12 02:07:24 UTC (rev 4077)
+++ MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/each_with_object_tags.txt 2010-05-12 02:14:49 UTC (rev 4078)
@@ -1,3 +0,0 @@
-fails:Enumerator#each_with_object returns an enumerator when not given a block
-fails:Enumerator#each_with_object returns the given object when given a block
-fails:Enumerator#each_with_object iterates over the array adding the given object
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_index_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_index_tags.txt 2010-05-12 02:07:24 UTC (rev 4077)
+++ MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_index_tags.txt 2010-05-12 02:14:49 UTC (rev 4078)
@@ -1,9 +0,0 @@
-fails:Enumerator#with_index accepts an optional argument when given a block
-fails:Enumerator#with_index accepts an optional argument when not given a block
-fails:Enumerator#with_index numbers indices from the given index when given an offset but no block
-fails:Enumerator#with_index numbers indices from the given index when given an offset and block
-fails:Enumerator#with_index raises a TypeError when the argument cannot be converted to numeric
-fails:Enumerator#with_index converts non-numeric arguments to Integer via #to_int
-fails:Enumerator#with_index coerces the given numeric argument to an Integer
-fails:Enumerator#with_index treats nil argument as no argument
-fails:Enumerator#with_index accepts negative argument
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_object_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_object_tags.txt 2010-05-12 02:07:24 UTC (rev 4077)
+++ MacRuby/trunk/spec/frozen/tags/macruby/core/enumerator/with_object_tags.txt 2010-05-12 02:14:49 UTC (rev 4078)
@@ -1,3 +0,0 @@
-fails:Enumerator#with_object returns an enumerator when not given a block
-fails:Enumerator#with_object returns the given object when given a block
-fails:Enumerator#with_object iterates over the array adding the given object
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100511/948b9a6a/attachment-0001.html>
More information about the macruby-changes
mailing list