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

ruby-changes:59811

From: Nobuyoshi <ko1@a...>
Date: Sun, 26 Jan 2020 19:51:22 +0900 (JST)
Subject: [ruby-changes:59811] d4e1d4e94e (master): Moved Array#sample to rbinc

https://git.ruby-lang.org/ruby.git/commit/?id=d4e1d4e94e

From d4e1d4e94e866d498ead1f370236df216917a6c7 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Sun, 26 Jan 2020 18:34:18 +0900
Subject: Moved Array#sample to rbinc


diff --git a/array.c b/array.c
index 42248db..c1f8071 100644
--- a/array.c
+++ b/array.c
@@ -5337,10 +5337,6 @@ rb_ary_flatten(int argc, VALUE *argv, VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L5337
     return result;
 }
 
-#define OPTHASH_GIVEN_P(opts) \
-    (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
-static ID id_random;
-
 #define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
 
 static VALUE
@@ -5373,55 +5369,16 @@ rb_ary_shuffle(rb_execution_context_t *ec, VALUE ary, VALUE randgen) https://github.com/ruby/ruby/blob/trunk/array.c#L5369
     return ary;
 }
 
-
-/*
- *  call-seq:
- *     ary.sample                  -> obj
- *     ary.sample(random: rng)     -> obj
- *     ary.sample(n)               -> new_ary
- *     ary.sample(n, random: rng)  -> new_ary
- *
- *  Choose a random element or +n+ random elements from the array.
- *
- *  The elements are chosen by using random and unique indices into the array
- *  in order to ensure that an element doesn't repeat itself unless the array
- *  already contained duplicate elements.
- *
- *  If the array is empty the first form returns +nil+ and the second form
- *  returns an empty array.
- *
- *     a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
- *     a.sample         #=> 7
- *     a.sample(4)      #=> [6, 4, 2, 5]
- *
- *  The optional +rng+ argument will be used as the random number generator.
- *
- *     a.sample(random: Random.new(1))     #=> 6
- *     a.sample(4, random: Random.new(1))  #=> [6, 10, 9, 2]
- */
-
-
 static VALUE
-rb_ary_sample(int argc, VALUE *argv, VALUE ary)
+rb_ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE to_array)
 {
-    VALUE nv, result;
-    VALUE opts, randgen = rb_cRandom;
+    VALUE result;
     long n, len, i, j, k, idx[10];
     long rnds[numberof(idx)];
     long memo_threshold;
 
-    if (OPTHASH_GIVEN_P(opts)) {
-	VALUE rnd;
-	ID keyword_ids[1];
-
-	keyword_ids[0] = id_random;
-	rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
-	if (rnd != Qundef) {
-	    randgen = rnd;
-	}
-    }
     len = RARRAY_LEN(ary);
-    if (rb_check_arity(argc, 0, 1) == 0) {
+    if (!to_array) {
 	if (len < 2)
 	    i = 0;
 	else
@@ -5429,7 +5386,6 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L5386
 
 	return rb_ary_elt(ary, i);
     }
-    nv = argv[0];
     n = NUM2LONG(nv);
     if (n < 0) rb_raise(rb_eArgError, "negative sample number");
     if (n > len) n = len;
@@ -7003,7 +6959,6 @@ Init_Array(void) https://github.com/ruby/ruby/blob/trunk/array.c#L6959
     rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
     rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
     rb_define_method(rb_cArray, "count", rb_ary_count, -1);
-    rb_define_method(rb_cArray, "sample", rb_ary_sample, -1);
     rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
     rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
     rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
@@ -7025,8 +6980,6 @@ Init_Array(void) https://github.com/ruby/ruby/blob/trunk/array.c#L6980
     rb_define_method(rb_cArray, "sum", rb_ary_sum, -1);
 
     rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
-
-    id_random = rb_intern("random");
 }
 
 #include "array.rbinc"
diff --git a/array.rb b/array.rb
index ed57792..25da88c 100755
--- a/array.rb
+++ b/array.rb
@@ -33,4 +33,31 @@ class Array https://github.com/ruby/ruby/blob/trunk/array.rb#L33
   def shuffle(random: Random)
     __builtin_rb_ary_shuffle(random);
   end
+
+  # call-seq:
+  #    ary.sample                  -> obj
+  #    ary.sample(random: rng)     -> obj
+  #    ary.sample(n)               -> new_ary
+  #    ary.sample(n, random: rng)  -> new_ary
+  #
+  # Choose a random element or +n+ random elements from the array.
+  #
+  # The elements are chosen by using random and unique indices into the array
+  # in order to ensure that an element doesn't repeat itself unless the array
+  # already contained duplicate elements.
+  #
+  # If the array is empty the first form returns +nil+ and the second form
+  # returns an empty array.
+  #
+  #    a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
+  #    a.sample         #=> 7
+  #    a.sample(4)      #=> [6, 4, 2, 5]
+  #
+  # The optional +rng+ argument will be used as the random number generator.
+  #
+  #    a.sample(random: Random.new(1))     #=> 6
+  #    a.sample(4, random: Random.new(1))  #=> [6, 10, 9, 2]
+  def sample(n = (ary = false), random: Random)
+    __builtin_rb_ary_sample(random, n, ary)
+  end
 end
diff --git a/spec/ruby/core/array/sample_spec.rb b/spec/ruby/core/array/sample_spec.rb
index 44be91b..87f8199 100644
--- a/spec/ruby/core/array/sample_spec.rb
+++ b/spec/ruby/core/array/sample_spec.rb
@@ -65,21 +65,24 @@ describe "Array#sample" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/sample_spec.rb#L65
   end
 
   describe "with options" do
-    it "calls #to_hash to convert the passed Object" do
-      obj = mock("array_sample")
-      obj.should_receive(:to_hash).and_return({})
-      obj.should_not_receive(:to_int)
-
-      [1, 2].sample(obj).should be_an_instance_of(Fixnum)
-    end
+    ruby_version_is ""..."2.8" do
+      # keyword argument since 2.8
+      it "calls #to_hash to convert the passed Object" do
+        obj = mock("array_sample")
+        obj.should_receive(:to_hash).and_return({})
+        obj.should_not_receive(:to_int)
+
+        [1, 2].sample(obj).should be_an_instance_of(Fixnum)
+      end
 
-    it "calls #to_int on the first argument and #to_hash on the second when passed Objects" do
-      count = mock("array_sample_count")
-      count.should_receive(:to_int).and_return(2)
-      options = mock("array_sample_options")
-      options.should_receive(:to_hash).and_return({})
+      it "calls #to_int on the first argument and #to_hash on the second when passed Objects" do
+        count = mock("array_sample_count")
+        count.should_receive(:to_int).and_return(2)
+        options = mock("array_sample_options")
+        options.should_receive(:to_hash).and_return({})
 
-      [1, 2].sample(count, options).size.should == 2
+        [1, 2].sample(count, options).size.should == 2
+      end
     end
 
     it "calls #rand on the Object passed by the :random key in the arguments Hash" do
-- 
cgit v0.10.2


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

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