2010-12-12 1 views
0

あいまいな質問を申し訳ありません。私はこの現象を説明する言葉のために失っているので、Googleはあまり役に立たなかった。次のコードを考えてみてください:ルビーが変数をこのように変更する方法は何ですか?

array = [["name", "age"]] 
a = [] 

x = ["Joe 32", 
    "Tom 45", 
    "Jim 36"] 

x.each do |line| 
    name, age = line.split(/\s/) 
    a[0] = name 
    a[1] = age 

    array.push(a) 
end 

array.each do |x| 
    puts x.join(" ") 
end 

これが生成します。

私は期待していたことに反している
name age 
Jim 36 
Jim 36 
Jim 36 

を:

name age 
Joe 32 
Tom 45 
Jim 36 

aを変更することで、事実の後array影響を受けているのはなぜ?

答えて

5

aeachの新しいArrayオブジェクトに設定します。現時点ではと同じaオブジェクトを配列にプッシュしています。そのため、同じ値が3回返されます。さらに良いことには全くaを使用して、代わりにこのようなものにコードを変換しないために、次のようになります。

x.each do |line| 
    name, age = line.split(/\s/) 
    array.push([name, age]) 
end 

は、あなたもpushメソッド内であることがline.splitを移動することによって、それよりも、それを小さくすることができますが、私はと思います読みやすさが損なわれ、splitからどの情報を取り除くのか説明しません。

+1

うんを与える

array.each_with_index do |object, index| puts "Object #{index} (which is #{object.inspect}) has an object id of #{object.object_id}" end 

は、あなたが場合でも、ポインタを理解する必要があります:さておき、あなたは、あなたがオブジェクトのそれぞれにobject_idを使用することができライアンの答えを確認したかったかのように

彼らはポインタと呼ばれていません。 –

+0

これはうまくいきませんが、私はまだオリジナルがなぜそうしたのか分かりません。私は指針を調べるだろうと思う。ありがとうございました – jack

0

これはもう少し進んでいるのではなく、

x.each do |line| 
    name, age = line.split(/\s/) 
    array.push([name, age]) 
end 

を行うよりも、ライアンの答えに構築するために、あなたはmap機能を使用することができ、そしてこれが、「もう少しです

people = x.map do |line| 
    name, age = line.split(/\s/) 
    [name, age] 
end 

desired_result = [["name", "age"]] + people 

を持っています関数型プログラミング "アプローチを採用しています。私はこれが非常に大まかな要約だと確信していますが、関数型プログラミングでは既存のオブジェクトを変更せず、代わりに新しいオブジェクトを作成するだけです。

Object 0 (which is ["name", "age"]) has an object id of 10204144 
Object 1 (which is ["Jim", "36"]) has an object id of 10248384 
Object 2 (which is ["Jim", "36"]) has an object id of 10248384 
Object 3 (which is ["Jim", "36"]) has an object id of 10248384 
+0

ありがとうアンドリュー。私はRubyで関数型プログラミングを調べることを意味してきました。これはそのようにする方法の素晴らしい例です。 – jack

+0

@jack:列挙型の列挙は、好きな一連のブログ記事です。 –

関連する問題