Ruby Block不会改变局部变量

时间:2017-11-07 07:38:54

标签: ruby scope block

这段代码在这里:

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]]

有人可以向我解释为什么它不旋转?我试图在对角线上得到一个带零的对称矩阵。

1 个答案:

答案 0 :(得分:2)

Task的文档解释了:

  

new(size = 0,默认= nil)
  新(数组)
   new(size){| index |阻止}
  ...

     

在最后一种形式中,创建了给定大小的数组。通过将元素的索引传递给给定块并存储返回值来创建此数组中的每个元素。

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

要解决此问题,您应该从块中返回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]]