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

ruby-changes:15419

From: marcandre <ko1@a...>
Date: Mon, 12 Apr 2010 05:12:54 +0900 (JST)
Subject: [ruby-changes:15419] Ruby:r27315 (trunk): * lib/matrix.rb: New method Matrix.build

marcandre	2010-04-12 05:10:43 +0900 (Mon, 12 Apr 2010)

  New Revision: 27315

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

  Log:
    * lib/matrix.rb: New method Matrix.build [ruby-core:28272]

  Modified files:
    trunk/ChangeLog
    trunk/lib/matrix.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27314)
+++ ChangeLog	(revision 27315)
@@ -1,3 +1,7 @@
+Mon Apr 12 05:10:20 2010  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* lib/matrix.rb: New method Matrix.build [ruby-core:28272]
+
 Mon Apr 12 03:45:25 2010  Marc-Andre Lafortune  <ruby-core@m...>
 
 	* lib/matrix.rb: Deprecate elements_to_{f/i/r}
Index: lib/matrix.rb
===================================================================
--- lib/matrix.rb	(revision 27314)
+++ lib/matrix.rb	(revision 27315)
@@ -48,6 +48,7 @@
 # * <tt> Matrix.[](*rows)               </tt>
 # * <tt> Matrix.rows(rows, copy = true) </tt>
 # * <tt> Matrix.columns(columns)        </tt>
+# * <tt> Matrix.build(row_size, column_size, &block) </tt>
 # * <tt> Matrix.diagonal(*values)       </tt>
 # * <tt> Matrix.scalar(n, value)        </tt>
 # * <tt> Matrix.identity(n)             </tt>
@@ -166,6 +167,30 @@
   end
 
   #
+  # Creates a matrix of size +row_size+ x +column_size+.
+  # It fills the values by calling the given block,
+  # passing the current row and column.
+  # Returns an enumerator if no block is given.
+  #
+  #   m = Matrix.build(2, 4) {|row, col| col - row }
+  #     => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
+  #   m = Matrix.build(3) { rand }
+  #     => a 3x3 matrix with random elements
+  #
+  def Matrix.build(row_size, column_size = row_size)
+    row_size = CoercionHelper.coerce_to_int(row_size)
+    column_size = CoercionHelper.coerce_to_int(column_size)
+    raise ArgumentError if row_size < 0 || column_size < 0
+    return to_enum :build, row_size, column_size unless block_given?
+    rows = row_size.times.map do |i|
+      column_size.times.map do |j|
+        yield i, j
+      end
+    end
+    new rows, column_size
+  end
+
+  #
   # Creates a matrix where the diagonal elements are composed of +values+.
   #   Matrix.diagonal(9, 5, -3)
   #     =>  9  0  0
@@ -1074,7 +1099,7 @@
 
   # Private helper module
 
-  module CoercionHelper
+  module CoercionHelper # :nodoc:
     def apply_through_coercion(obj, oper)
       coercion = obj.coerce(self)
       raise TypeError unless coercion.is_a?(Array) && coercion.length == 2
@@ -1083,6 +1108,27 @@
       raise TypeError, "#{obj.inspect} can't be coerced into #{self.class}"
     end
     private :apply_through_coercion
+
+    # Helper method to coerce a value into a specific class.
+    # Raises a TypeError if the coercion fails or the returned value
+    # is not of the right class.
+    # (from Rubinius)
+    def self.coerce_to(obj, cls, meth) # :nodoc:
+      return obj if obj.kind_of?(cls)
+
+      begin
+        ret = obj.__send__(meth)
+      rescue Exception => e
+        raise TypeError, "Coercion error: #{obj.inspect}.#{meth} => #{cls} failed:\n" \
+                         "(#{e.message})"
+      end
+      raise TypeError, "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{ret.class})" unless ret.kind_of? cls
+      ret
+    end
+
+    def self.coerce_to_int(obj)
+      coerce_to(obj, Integer, :to_int)
+    end
   end
 
   include CoercionHelper

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

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