Arrayクラス
配列オブジェクトの元になっているクラスはArrayクラスです。配列オブジェクトを作成するにはArrayクラスのクラスメソッドを使うこともできます。いくつか用意されていますので一つ一つ確認していきます。
Array[item,...]
1つ目はクラスメソッドの[]を使用した形式です。最初のページで使用した配列オブジェクトの作り方は今回の形式でArrayを省略したものと考えることが出来ます。
Array[item,...]
オブジェクトをカンマ(,)で区切って指定します。指定したオブジェクトの数だけの要素を持つ配列オブジェクトが作成され、各要素には引数に指定したオブジェクトが順に代入されます。
具体的には次の様に記述します。
array = Array[2005, 2006, 2007, 2008]
4つの要素を持ち、それぞれ数値オブジェクトが代入された配列オブジェクトが作成されます。
Array.new([size[, val]])
2つ目はクラスメソッドの「new」を使用した形式です。
Array.new([size[, val]])
作成する要素数だけを指定します。要素数を省略した場合は空の配列オブジェクトが作成されます。
具体的には次の様に記述します。
array1 = Array.new(3) array2 = Array.new
要素数だけを指定した場合、各要素には初期値としてのオブジェクトが代入されていませんので「nil」が代入されます。よって次のように配列オブジェクトを作成した場合と同じです。
array1 = [nil, nil, nil]
また要素に代入するオブジェクトを指定することも可能です。
array = Array.new(3, "Red")
指定した要素数の数だけ要素を作成すると同時に、各要素に2番目に指定したオブジェクトを代入します。この形式で配列を作成した場合、各要素には全て同一のオブジェクトが代入されますので注意が必要です。次の例を見てください。
array1 = ["Red", "Red", "Red"] array2 = Array.new(3, "Red")
最初の例では、各要素には「Red」と言う文字列オブジェクトが各要素に代入されます。これらのオブジェクトは値は「Red」で同じですがオブジェクトとしては全て別のオブジェクトです。
それに対して2つ目の例では「Red」と言う文字列オブジェクトが1つだけ作成され全ての要素に代入されます。各要素は同じオブジェクトを参照していることになります。よって文字列オブジェクトを何らかの方法で変更すると全ての要素が参照しているオブジェクトに影響が出ます。
別々のオブジェクトを作成して要素に格納したい場合には次のブロック付きメソッドを利用して下さい。
Array.new(size) {|index| ... }
3つ目はブロック付きのクラスメソッドの「new」を使用した場合です。
Array.new(size) {|index| ... }
作成する要素数を指定します。そしてブロック内で各要素に対して代入するオブジェクトを作成するための処理を記述します。
具体的には次の様に記述します。
array = Array.new(3){"Red"}
この場合、要素数が3つの配列オブジェクトが作成されますが、各要素に対してブロック内の処理が呼び出されて実行されます。今回は単に文字列オブジェクトの「Red」を記述しています。この場合は各要素に「Red」が格納されますが、要素毎に毎回オブジェクトが作成されて代入されているため各要素には値は同じですが別々の文字列オブジェクトが代入されます。
Array.new(ary)
4つ目はクラスメソッドの「new」の引数に他の配列オブジェクト指定した場合です。
Array.new(ary)
引数に指定した配列オブジェクトが複製された配列オブジェクトが作成されます。この時、元になっている配列オブジェクトと複製された配列オブジェクトの同じ位置にある要素は、同じオブジェクトを参照しています。
具体的には次の様に記述します。
array = ["Red", "Red"] newarray = Array.new(array)
上記の場合、配列オブジェクト「array」の0番目の要素と1番目の要素に代入されているオブジェクトは別々のものでが、複製された配列オブジェクト「newarray」の0番目の要素に代入されているオブジェクトは、元の配列オブジェクト「array」の0番目の要素に代入されているオブジェクトは同一です。
配列オブジェクトの作成はここまでのいずれかの方法で行いますが、作成と同時にオブジェクトを要素に代入する方法を使う場合は、同じオブジェクトなのか別のオブジェクトなのかは注意して使用して下さい。
サンプルプログラム
では簡単なプログラムで確認して見ます。
#! ruby -Ku require "kconv" array1 = Array["Red", "Red"] print('Array["Red", "Red"]' + "¥n"); print(array1[0].object_id, "¥n") print(array1[1].object_id, "¥n") array2 = Array.new(2, "Red") print('Array.new(2, "Red")' + "¥n"); print(array2[0].object_id, "¥n") print(array2[1].object_id, "¥n") array3 = Array.new(2){"Red"} print('Array.new(2){"Red"}' + "¥n"); print(array3[0].object_id, "¥n") print(array3[1].object_id, "¥n") array4 = Array.new(array1) print('Array.new(array1)' + "¥n"); print(array4[0].object_id, "¥n") print(array4[1].object_id, "¥n")
上記のプログラムを「test3-1.rb」として保存します。文字コードはUTF-8です。そして下記のように実行して下さい。
「Array.new(2, "Red")」で作成した配列オブジェクトは、2つの要素に代入されているオブジェクトが同じです。また「Array.new(array1)」で作成したオブジェクトは元になっている配列オブジェクトと、対応する要素に代入されているオブジェクトが同じです。
( Written by Tatsuo Ikura )