Ruby 块不会改变局部变量

Ruby Block won't change local variable

此处代码:

def create_sym_matrix
  ran_arr = Array.new(5){rand(1..100)}
  ran_arr[1] = 0
  mat_arr = Array.new(5){|i|ran_arr.push(ran_arr.shift)}
  Matrix.columns(mat_arr)
end

aa = create_sym_matrix

=> Matrix[[86, 86, 86, 86, 86], [0, 0, 0, 0, 0], [20, 20, 20, 20, 20], 
[39, 39, 39, 39, 39], [48, 48, 48, 48, 48]]

谁能解释一下为什么它没有旋转?我试图得到一个在对角线上有零的对称矩阵。

Array::new 的文档解释:

new(size=0, default=nil)
new(array)
new(size) {|index| block }
...

In the last form, an array of the given size is created. Each element in this array is created by passing the element's index to the given block and storing the return value.

{|i|ran_arr.push(ran_arr.shift)} 始终 return 具有相同的值:存储在 ran_arr 中的数组。新数组包含 5 个对 ran_arr 的引用。 mat_arr 的行包含相同的值,因为没有五个不同的行;这是同一个对象链接了五次。

要解决此问题,您应该 return 从块中复制 ran_arr:

  mat_arr = Array.new(5){|i|ran_arr.push(ran_arr.shift).clone}

您会注意到它仍然没有生成对角线为零的矩阵。为了实现这个目标你需要修正算法:

def create_sym_matrix
  ran_arr = Array.new(5){rand(1..100)}
  ran_arr[4] = 0
  mat_arr = Array.new(5){|i|ran_arr.unshift(ran_arr.pop).clone}
  Matrix.columns(mat_arr)
end

输出:

Matrix[[0, 38, 8, 48, 73], [73, 0, 38, 8, 48], [48, 73, 0, 38, 8], [8, 48, 73, 0, 38], [38, 8, 48, 73, 0]]