[#14696] Inconsistency in rescuability of "return" — Charles Oliver Nutter <charles.nutter@...>

Why can you not rescue return, break, etc when they are within

21 messages 2008/01/02
[#14699] Re: Inconsistency in rescuability of "return" — Gary Wright <gwtmp01@...> 2008/01/02

[#14738] Enumerable#zip Needs Love — James Gray <james@...>

The community has been building a Ruby 1.9 compatibility tip list on

15 messages 2008/01/03
[#14755] Re: Enumerable#zip Needs Love — Martin Duerst <duerst@...> 2008/01/04

Hello James,

[#14772] Manual Memory Management — Pramukta Kumar <prak@...>

I was thinking it would be nice to be able to free large objects at

36 messages 2008/01/04
[#14788] Re: Manual Memory Management — Marcin Raczkowski <mailing.mr@...> 2008/01/05

I would only like to add that RMgick for example provides free method to

[#14824] Re: Manual Memory Management — MenTaLguY <mental@...> 2008/01/07

On Sat, 5 Jan 2008 15:49:30 +0900, Marcin Raczkowski <mailing.mr@gmail.com> wrote:

[#14825] Re: Manual Memory Management — "Evan Weaver" <evan@...> 2008/01/07

Python supports 'del reference', which decrements the reference

[#14838] Re: Manual Memory Management — Marcin Raczkowski <mailing.mr@...> 2008/01/08

Evan Weaver wrote:

[#14911] Draft of some pages about encoding in Ruby 1.9 — Dave Thomas <dave@...>

Folks:

24 messages 2008/01/10

[#14976] nil encoding as synonym for binary encoding — David Flanagan <david@...>

The following just appeared in the ChangeLog

37 messages 2008/01/11
[#14977] Re: nil encoding as synonym for binary encoding — Yukihiro Matsumoto <matz@...> 2008/01/11

Hi,

[#14978] Re: nil encoding as synonym for binary encoding — Dave Thomas <dave@...> 2008/01/11

[#14979] Re: nil encoding as synonym for binary encoding — David Flanagan <david@...> 2008/01/11

Dave Thomas wrote:

[#14993] Re: nil encoding as synonym for binary encoding — Dave Thomas <dave@...> 2008/01/11

[#14980] Re: nil encoding as synonym for binary encoding — Gary Wright <gwtmp01@...> 2008/01/11

[#14981] Re: nil encoding as synonym for binary encoding — Yukihiro Matsumoto <matz@...> 2008/01/11

Hi,

[#14995] Re: nil encoding as synonym for binary encoding — David Flanagan <david@...> 2008/01/11

Yukihiro Matsumoto writes:

[#15050] how to "borrow" the RDoc::RubyParser and HTMLGenerator — Phlip <phlip2005@...>

Core Rubies:

17 messages 2008/01/13
[#15060] Re: how to "borrow" the RDoc::RubyParser and HTMLGenerator — Eric Hodel <drbrain@...7.net> 2008/01/14

On Jan 13, 2008, at 08:54 AM, Phlip wrote:

[#15062] Re: how to "borrow" the RDoc::RubyParser and HTMLGenerator — Phlip <phlip2005@...> 2008/01/14

Eric Hodel wrote:

[#15073] Re: how to "borrow" the RDoc::RubyParser and HTMLGenerator — Eric Hodel <drbrain@...7.net> 2008/01/14

On Jan 13, 2008, at 20:35 PM, Phlip wrote:

[#15185] Friendlier methods to compare two Time objects — "Jim Cropcho" <jim.cropcho@...>

Hello,

10 messages 2008/01/22

[#15194] Can large scale projects be successful implemented around a dynamic programming language? — Jordi <mumismo@...>

A good article I have found (may have been linked by slashdot, don't know)

8 messages 2008/01/24

[#15248] Symbol#empty? ? — "David A. Black" <dblack@...>

Hi --

24 messages 2008/01/28
[#15250] Re: Symbol#empty? ? — Yukihiro Matsumoto <matz@...> 2008/01/28

Hi,

Re: Enumerable#zip Needs Love

From: Yukihiro Matsumoto <matz@...>
Date: 2008-01-08 05:06:14 UTC
List: ruby-core #14837
Hi,

In message "Re: Enumerable#zip Needs Love"
    on Tue, 8 Jan 2008 13:50:09 +0900, James Gray <james@grayproductions.net> writes:

|>  (a) stopping at the shortest

|* With the 1.8 system, we easily can have it both ways.  We can find  
|the bigger group and lead with that to save all data, or find the  
|shorter group and lead with it to trim data.
|* Under 1.9 we lose data by default and it's challenging to save it  
|since all groups must be expanded to the same length.

Points taken.

|>   (b) return value

|* An Array is a super set of Enumerable, so we gain more options  
|without losing anything.

Although an array is a Enumerable, and implements every methods in
Enumerable, I still hesitate to call it "super set", just because it
introduces several restriction of Enumerable, for example non infinity
length.  This is typical super set/sub set issue.

But using zip to create zipped array is certainly important use-case,
and consistency is not the primary goal of Ruby's design.

|* It seems to break a fair bit of 1.8 code.  I can name three  
|libraries affected by the change off the top of my head.
|* Performance seems like another good reason to do this, since you  
|said it would speed things up.

Points taken.

|> But use-case is more important than theoretical rationale.  There are
|> several options we can take:
|>
|>  (3) hardest way - (2) + honoring length of the receiver
|>
|>      I am not sure how to implement it yet.
|
|I don't understand.  We had this in 1.8.  Can we not go back to that  
|code?

The internal was totally re-written in 1.9 using fiber, but that's OK.
It's our matter.  In fact, I figured out how to do it while waiting
for your reply.  And actually implemented it already.  See attached
patch.

							matz.

diff --git a/enum.c b/enum.c
index 04fade3..bf18e27 100644
--- a/enum.c
+++ b/enum.c
@@ -1347,6 +1347,36 @@ enum_each_with_index(int argc, VALUE *argv, VALUE obj)
 
 
 static VALUE
+zip_a(VALUE val, NODE *memo, int argc, VALUE *argv)
+{
+    volatile VALUE result = memo->u1.value;
+    volatile VALUE args = memo->u2.value;
+    volatile VALUE tmp;
+    long idx = memo->u3.cnt++;
+    int i;
+
+    tmp = rb_ary_new2(RARRAY_LEN(args) + 1);
+    rb_ary_store(tmp, 0, val);
+    for (i=0; i<RARRAY_LEN(args); i++) {
+	rb_ary_push(tmp, rb_ary_entry(RARRAY_PTR(args)[i], idx));
+    }
+    rb_ary_push(result, tmp);
+    return Qnil;
+}
+
+static VALUE
+call_next(VALUE *v)
+{
+    return v[0] = rb_funcall(v[1], id_next, 0, 0);
+}
+
+static VALUE
+call_stop(VALUE *v)
+{
+    return v[0] = Qundef;
+}
+
+static VALUE
 zip_i(VALUE val, NODE *memo, int argc, VALUE *argv)
 {
     volatile VALUE result = memo->u1.value;
@@ -1357,8 +1387,20 @@ zip_i(VALUE val, NODE *memo, int argc, VALUE *argv)
     tmp = rb_ary_new2(RARRAY_LEN(args) + 1);
     rb_ary_store(tmp, 0, enum_values_pack(argc, argv));
     for (i=0; i<RARRAY_LEN(args); i++) {
-	VALUE v = rb_funcall(RARRAY_PTR(args)[i], id_next, 0, 0);
-	rb_ary_push(tmp, v);
+	if (NIL_P(RARRAY_PTR(args)[i])) {
+	    rb_ary_push(tmp, Qnil);
+	}
+	else {
+	    VALUE v[2];
+
+	    v[1] = RARRAY_PTR(args)[i];
+	    rb_rescue2(call_next, (VALUE)v, call_stop, (VALUE)v, rb_eStopIteration, 0);
+	    if (v[0] == Qundef) {
+		RARRAY_PTR(args)[i] = Qnil;
+		v[0] = Qnil;
+	    }
+	    rb_ary_push(tmp, v[0]);
+	}
     }
     if (NIL_P(result)) {
 	rb_yield(tmp);
@@ -1369,12 +1411,6 @@ zip_i(VALUE val, NODE *memo, int argc, VALUE *argv)
     return Qnil;
 }
 
-static VALUE
-zip_b(NODE *memo)
-{
-    return rb_block_call(memo->u3.value, id_each, 0, 0, zip_i, (VALUE)memo);
-}
-
 /*
  *  call-seq:
  *     enum.zip(arg, ...)                   => enumerator
@@ -1400,19 +1436,30 @@ zip_b(NODE *memo)
 static VALUE
 enum_zip(int argc, VALUE *argv, VALUE obj)
 {
-    int i;
-    VALUE result;
+    int i, block;
+    ID conv;
     NODE *memo;
 
-    for (i=0; i<argc; i++) {
-	argv[i] = rb_funcall(argv[i], rb_intern("to_enum"), 1, ID2SYM(id_each));
+    
+    if (!rb_block_given_p()) {
+	conv = rb_intern("to_a");
+	for (i=0; i<argc; i++) {
+	    argv[i] = rb_funcall(argv[i], conv, 0, 0);
+	}
+	memo = rb_node_newnode(NODE_MEMO, rb_ary_new(), rb_ary_new4(argc, argv), 0);
+	rb_block_call(obj, id_each, 0, 0, zip_a, (VALUE)memo);
+
+	return memo->u1.value;
     }
-    RETURN_ENUMERATOR(obj, argc, argv);
-    result = rb_block_given_p() ? Qnil : rb_ary_new();
-    memo = rb_node_newnode(NODE_MEMO, result, rb_ary_new4(argc, argv), obj);
-    rb_rescue2(zip_b, (VALUE)memo, 0, 0, rb_eStopIteration, (VALUE)0);
+    else {
+	conv = rb_intern("to_enum");
+	for (i=0; i<argc; i++) {
+	    argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
+	}
+	memo = rb_node_newnode(NODE_MEMO, Qnil, rb_ary_new4(argc, argv), 0);
 
-    return result;
+	return rb_block_call(obj, id_each, 0, 0, zip_i, (VALUE)memo);
+    }
 }
 
 static VALUE
diff --git a/enumerator.c b/enumerator.c
index 0474469..d9179db 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -365,9 +365,9 @@ enumerator_with_index(VALUE obj)
 }
 
 static VALUE
-next_ii(VALUE i, VALUE obj)
+next_ii(VALUE i, VALUE obj, int argc, VALUE *argv)
 {
-    rb_fiber_yield(1, &i);
+    rb_fiber_yield(argc, argv);
     return Qnil;
 }
 

In This Thread