Commits

Xavier Noria  committed ed8cabc

deprecates Array#random_element in favor of Array#sample, backported from Ruby 1.9, thanks to Marc-Andre Lafortune

  • Participants
  • Parent commits 3d6ed50
  • Branches 2-3-stable

Comments (0)

Files changed (5)

File activerecord/test/cases/associations/eager_load_nested_include_test.rb

 
   module ClassMethods
     def remembered; @@remembered ||= []; end
-    def random_element; @@remembered.random_element; end
+    def sample; @@remembered.sample; end
   end
 end
 
       [Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!)
     end
     1.upto(NUM_SIMPLE_OBJS) do
-      PaintColor.create!(:non_poly_one_id => NonPolyOne.random_element.id)
-      PaintTexture.create!(:non_poly_two_id => NonPolyTwo.random_element.id)
+      PaintColor.create!(:non_poly_one_id => NonPolyOne.sample.id)
+      PaintTexture.create!(:non_poly_two_id => NonPolyTwo.sample.id)
     end
     1.upto(NUM_SHAPE_EXPRESSIONS) do
-      shape_type = [Circle, Square, Triangle].random_element
-      paint_type = [PaintColor, PaintTexture].random_element
-      ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.random_element.id,
-                              :paint_type => paint_type.to_s, :paint_id => paint_type.random_element.id)
+      shape_type = [Circle, Square, Triangle].sample
+      paint_type = [PaintColor, PaintTexture].sample
+      ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.sample.id,
+                              :paint_type => paint_type.to_s, :paint_id => paint_type.sample.id)
     end
   end
 

File activerecord/test/cases/named_scope_test.rb

   end
 
   def test_rand_should_select_a_random_object_from_proxy
-    assert Topic.approved.random_element.is_a?(Topic)
+    assert Topic.approved.sample.is_a?(Topic)
   end
 
   def test_should_use_where_in_query_for_named_scope

File activesupport/CHANGELOG

 *2.3.9 (unreleased)*
 
-* ...
+* Deprecates Array#random_element in favor of Array#sample, backported from Ruby 1.9, thanks to 
+Marc-Andre Lafortune. [fxn]
 
 
 *2.3.8 (May 24, 2010)*

File activesupport/lib/active_support/core_ext/array/random_access.rb

         #   https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4555
         #
         def rand # :nodoc:
-          ActiveSupport::Deprecation.warn 'Array#rand is deprecated and will be removed in Rails 3. Use "random_element" instead', caller
-          random_element
+          ActiveSupport::Deprecation.warn 'Array#rand is deprecated and will be removed in Rails 3. Use Array#sample instead', caller
+          sample
         end
 
         # Returns a random element from the array.
-        def random_element
-          self[Kernel.rand(length)]
+        def random_element # :nodoc:
+          ActiveSupport::Deprecation.warn 'Array#random_element is deprecated and will be removed in Rails 3. Use Array#sample instead', caller
+          sample
         end
+
+        # Backport of Array#sample based on Marc-Andre Lafortune's http://github.com/marcandre/backports/
+        def sample(n=nil)
+          return self[Kernel.rand(size)] if n.nil?
+          n = n.to_int
+        rescue Exception => e
+          raise TypeError, "Coercion error: #{n.inspect}.to_int => Integer failed:\n(#{e.message})"
+        else
+          raise TypeError, "Coercion error: #{n}.to_int did NOT return an Integer (was #{n.class})" unless n.kind_of? ::Integer
+          raise ArgumentError, "negative array size" if n < 0
+          n = size if n > size
+          result = ::Array.new(self)
+          n.times do |i|
+            r = i + Kernel.rand(size - i)
+            result[i], result[r] = result[r], result[i]
+          end
+          result[n..size] = []
+          result
+        end unless method_defined? :sample
       end
     end
   end

File activesupport/test/core_ext/array_ext_test.rb

 end
 
 class ArrayExtRandomTests < ActiveSupport::TestCase
-  def test_random_element_from_array
-    assert_nil [].random_element
-
-    Kernel.expects(:rand).with(1).returns(0)
-    assert_equal 'x', ['x'].random_element
+  def test_sample_from_array
+    assert_nil [].sample
+    assert_equal [], [].sample(5)
+    assert_equal 42, [42].sample
+    assert_equal [42], [42].sample(5)
+
+    a = [:foo, :bar, 42]
+    s = a.sample(2)
+    assert_equal 2, s.size
+    assert_equal 1, (a-s).size
+    assert_equal [], a-(0..20).sum{a.sample(2)}
+  
+    o = Object.new
+    def o.to_int; 1; end
+    assert_equal [0], [0].sample(o)
+  
+    o = Object.new
+    assert_raises(TypeError) { [0].sample(o) }
+    
+    o = Object.new
+    def o.to_int; ''; end
+    assert_raises(TypeError) { [0].sample(o) }
 
-    Kernel.expects(:rand).with(3).returns(1)
-    assert_equal 2, [1, 2, 3].random_element
+    assert_raises(ArgumentError) { [0].sample(-7) }
   end
 
   def test_deprecated_rand_on_array
     assert_deprecated { [].rand }
   end
+
+  def test_deprecated_random_element_on_array
+    assert_deprecated { [].random_element }
+  end
 end
 
 class ArrayWrapperTests < Test::Unit::TestCase