2017-12-12 7 views
0

私は方法があります:ルビーでは、これは2次元配列のバグですか?

def test 
    f = Array.new(4,Array.new(4,false)) 
    f.each do |array| 
     p array.inspect 
    end 
    f[1][1] = true 
    p "after setting f[1][1]" 
    f.each do |array| 
     p array.inspect 
    end 
end 

は、これが出力されます。

"[false, false, false, false]" 
"[false, false, false, false]" 
"[false, false, false, false]" 
"[false, false, false, false]" 
"after setting f[1][1]" 
"[false, true, false, false]" 
"[false, true, false, false]" 
"[false, true, false, false]" 
"[false, true, false, false]" 

あなたは、なぜそれが起こる可能性があり、列1内のすべての値がtrueになった見ることができるように?

+0

いいえ、バグではありません。 'Array.new(4、Array.new(4、false))'は 'fの各行を' Array.new(4、false) 'から*同じ* 4要素配列に設定します。 'Array.new(4、false)'を4回実行しません。したがって、 'f'は同じ4要素オブジェクトへの4つの参照の配列です。 – lurker

+1

はい、コードにバグがあります。 –

+0

@lurker hah、それは本当にトリッキーです。指摘していただきありがとうございます。 – GavinLuo

答えて

1

これはバグではありません。 Array.new(4, Array.new(4,false))は、各要素がと同じ配列オブジェクトであり、Array.new(4, false)を1回呼び出すことによって決定される4つの要素の配列を作成します。 fの各要素に対して1回、Array.new(4,false)を4回実行しません。したがって、fは、同じオブジェクト(単一の4要素配列、[false, false, false, false])への4つの参照の配列として終わります。

4つの異なる4要素配列の配列を作成したい場合、Rubyでこれを行う方法はたくさんあります。一つの方法は次のとおりです。

f = Array.new(4) { Array.new(4, false) } 

これはあなたのArray.new(4)内の各エントリに対して個別にArray.new(4, false)を実行します。

2.4.0 :002 > f = Array.new(4) { Array.new(4, false) } 
=> [[false, false, false, false], [false, false, false, false], [false, false, false, false], [false, false, false, false]] 
2.4.0 :003 > f.each do |array| 
2.4.0 :004 > p array.inspect 
2.4.0 :005?> end 
"[false, false, false, false]" 
"[false, false, false, false]" 
"[false, false, false, false]" 
"[false, false, false, false]" 
=> [[false, false, false, false], [false, false, false, false], [false, false, false, false], [false, false, false, false]] 
2.4.0 :006 > f[1][1] = true 
=> true 
2.4.0 :007 > p "after setting f[1][1]" 
"after setting f[1][1]" 
=> "after setting f[1][1]" 
2.4.0 :008 > f.each do |array| 
2.4.0 :009 > p array.inspect 
2.4.0 :010?> end 
"[false, false, false, false]" 
"[false, true, false, false]" 
"[false, false, false, false]" 
"[false, false, false, false]" 
=> [[false, false, false, false], [false, true, false, false], [false, false, false, false], [false, false, false, false]] 
2.4.0 :011 > 

参考までに、Creating ArraysのRubyドキュメントを参照してください。