Ruby では常に変数を初期化する必要があります。ただし、次のようにハッシュを初期化できます。
# Using {} to creates an empty hash
months = {}
# or create a new empty hash object from Hash class
months = Hash.new
# instead of
months = {"Feb"=>["day1", "day2"]}
ハッシュ内の配列を初期化するには:
# Array.new creates a new Array with size 5
# And values within Hash.new block are the default values for the hash
# i.e. When you call the Hash#[], it creates a new array of size 5
months = Hash.new { |hash, key| hash[key] = Array.new(5) }
puts months #=> {}
puts months["Feb"] # Here the Hash creates a new Array inside "Feb" key
puts months #=> {"Feb" => [nil, nil, nil, nil, nil]}
puts months["Feb"][3] = "Day3"
puts months #=> {"Feb" => [nil, nil, nil, "Day3", nil]}
未定義の配列サイズを使用して同じことを行うには:
months = Hash.new { |hash, key| hash[key] = [] }
puts months #=> {}
months["Feb"].push "Day0"
puts months #=> {"Feb" => ["Day0"]}
months["Feb"].push "Day1"
puts months #=> {"Feb" => ["Day0", "Day1"]}
よりエレガントなアプローチは、 map メソッドを使用して日の配列を作成してから、「Feb」キーにバインドすることだと思います。
months = {"Feb" => (0..4).map{ |i| "day#{i}" }}
# => {"Feb"=>["day0", "day1", "day2", "day3", "day4"]}
月の名前を入力したくない場合は、Date クラスを要求し、Fixnum を渡して月の名前を取得できます。
require 'date'
months = {Date::ABBR_MONTHNAMES[2] => (0..4).map{ |i| "day#{i}"}}
# => {"Feb"=>["day0", "day1", "day2", "day3", "day4"]}
すべての月に同じ構造を生成するには、次のようにします。
days = (0..4).map{ |d| "day#{d}"}
months = (1..12).map{ |m| {Date::ABBR_MONTHNAMES[m] => days }}
# => {"Jan"=>["day0", "day1", "day2", "day3", "day4"],
# "Feb"=>["day0", "day1", "day2", "day3", "day4"],
# ...
# "Dec"=>["day0", "day1", "day2", "day3", "day4"]}
いくつかの有用なドキュメント: