[前][次][番号順一覧][スレッド一覧]

ruby-changes:32275

From: marcandre <ko1@a...>
Date: Mon, 23 Dec 2013 12:42:41 +0900 (JST)
Subject: [ruby-changes:32275] marcandRe: r44354 (trunk): * array.c: Have to_h raise on elements that are not key-value pairs [#9239]

marcandre	2013-12-23 12:42:29 +0900 (Mon, 23 Dec 2013)

  New Revision: 44354

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44354

  Log:
    * array.c: Have to_h raise on elements that are not key-value pairs [#9239]
    
    * enum.c: ditto

  Modified files:
    trunk/ChangeLog
    trunk/array.c
    trunk/enum.c
    trunk/test/ruby/test_array.rb
    trunk/test/ruby/test_enum.rb
Index: array.c
===================================================================
--- array.c	(revision 44353)
+++ array.c	(revision 44354)
@@ -2130,8 +2130,7 @@ rb_ary_to_a(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L2130
  *     ary.to_h     -> hash
  *
  *  Returns the result of interpreting <i>ary</i> as an array of
- *  <tt>[key, value]</tt> pairs. Elements other than pairs of
- *  values are ignored.
+ *  <tt>[key, value]</tt> pairs.
  *
  *     [[:foo, :bar], [1, 2]].to_h
  *       # => {:foo => :bar, 1 => 2}
@@ -2144,9 +2143,15 @@ rb_ary_to_h(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L2143
     VALUE hash = rb_hash_new();
     for (i=0; i<RARRAY_LEN(ary); i++) {
 	VALUE key_value_pair = rb_check_array_type(rb_ary_elt(ary, i));
-	if (!NIL_P(key_value_pair) && (RARRAY_LEN(key_value_pair) == 2)) {
-	    rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
+	if (NIL_P(key_value_pair)) {
+	    rb_raise(rb_eTypeError, "wrong element type %s at %ld (expected array)",
+		rb_builtin_class_name(rb_ary_elt(ary, i)), i);
 	}
+	if (RARRAY_LEN(key_value_pair) != 2) {
+	    rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
+		i, RARRAY_LEN(key_value_pair));
+	}
+	rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
     }
     return hash;
 }
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 44353)
+++ ChangeLog	(revision 44354)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Dec 23 12:42:13 2013  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* array.c: Have to_h raise on elements that are not key-value pairs
+	  [#9239]
+
+	* enum.c: ditto
+
 Mon Dec 23 05:01:55 2013  Zachary Scott  <e@z...>
 
 	* doc/syntax/methods.rdoc: [DOC] Added example for underscore
Index: enum.c
===================================================================
--- enum.c	(revision 44353)
+++ enum.c	(revision 44354)
@@ -512,12 +512,19 @@ enum_to_a(int argc, VALUE *argv, VALUE o https://github.com/ruby/ruby/blob/trunk/enum.c#L512
 static VALUE
 enum_to_h_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
 {
+    VALUE key_value_pair;
     ENUM_WANT_SVALUE();
     rb_thread_check_ints();
-    i = rb_check_array_type(i);
-    if (!NIL_P(i) && RARRAY_LEN(i) == 2) {
-	rb_hash_aset(hash, RARRAY_AREF(i, 0), RARRAY_AREF(i, 1));
+    key_value_pair = rb_check_array_type(i);
+    if (NIL_P(key_value_pair)) {
+	rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
+	    rb_builtin_class_name(i));
     }
+    if (RARRAY_LEN(key_value_pair) != 2) {
+        rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
+	    RARRAY_LEN(key_value_pair));
+    }
+    rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
     return Qnil;
 }
 
@@ -526,8 +533,7 @@ enum_to_h_i(RB_BLOCK_CALL_FUNC_ARGLIST(i https://github.com/ruby/ruby/blob/trunk/enum.c#L533
  *     enum.to_h(*args)  -> hash
  *
  *  Returns the result of interpreting <i>enum</i> as a list of
- *  <tt>[key, value]</tt> pairs. Elements other than pairs of
- *  values are ignored.
+ *  <tt>[key, value]</tt> pairs.
  *
  *     %i[hello world].each_with_index.to_h
  *       # => {:hello => 0, :world => 1}
Index: test/ruby/test_array.rb
===================================================================
--- test/ruby/test_array.rb	(revision 44353)
+++ test/ruby/test_array.rb	(revision 44354)
@@ -1467,12 +1467,18 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1467
     end
     array = [
       [:key, :value],
-      [:ignore_me],
-      [:ignore, :me, :too],
-      :ignore_me,
       kvp,
     ]
     assert_equal({key: :value, obtained: :via_to_ary}, array.to_h)
+
+    e = assert_raise(TypeError) {
+      [[:first_one, :ok], :not_ok].to_h
+    }
+    assert_equal "wrong element type Symbol at 1 (expected array)", e.message
+    e = assert_raise(ArgumentError) {
+      [[:first_one, :ok], [1, 2], [:not_ok]].to_h
+    }
+    assert_equal "wrong array length at 2 (expected 2, was 1)", e.message
   end
 
   def test_uniq
Index: test/ruby/test_enum.rb
===================================================================
--- test/ruby/test_enum.rb	(revision 44353)
+++ test/ruby/test_enum.rb	(revision 44354)
@@ -104,17 +104,11 @@ class TestEnumerable < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_enum.rb#L104
   end
 
   def test_to_h
-    assert_equal({}, @obj.to_h)
     obj = Object.new
     def obj.each(*args)
-      yield args
+      yield *args
       yield [:key, :value]
-      yield [:ignore_me]
-      yield [:ignore, :me, :too]
       yield :other_key, :other_value
-      yield :ignore_me
-      yield :ignore, :me, :too
-      yield
       kvp = Object.new
       def kvp.to_ary
         [:obtained, :via_to_ary]
@@ -128,6 +122,16 @@ class TestEnumerable < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_enum.rb#L122
       :other_key => :other_value,
       :obtained => :via_to_ary,
     }, obj.to_h(:hello, :world))
+
+    e = assert_raise(TypeError) {
+      obj.to_h(:not_an_array)
+    }
+    assert_equal "wrong element type Symbol (expected array)", e.message
+
+    e = assert_raise(ArgumentError) {
+      obj.to_h([1])
+    }
+    assert_equal "element has wrong array length (expected 2, was 1)", e.message
   end
 
   def test_inject

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]