Ruby

[Ruby]配列の要素ごとに別々のブロック変数で扱う

はじめに

ブロック変数の配列について、配列の添字で指定する方法はこう

people = {
#  name  => data
  '太郎' => ['東京', 30, 'プログラマー'],
  '花子' => ['大阪', 20, '学生']
}

# dataに添字で指定
people.each do |name, data|
  puts "#{name}#{data[0]}に住む#{data[1]}才の#{data[2]}です."
end
#=> 太郎は東京に住む30才のプログラマーです.
#   花子は大阪に住む20才の学生です.

何を表しているのか、添字だとわかりづらいです。

なので配列の要素ごとに異なるブロック変数で扱いたいです。
でも要素数だけ変数をならべても、配列が展開されないのでうまくできません。

# これだとダメ
people.each do |name, place, age, job|
  puts "#{name}#{place}に住む#{age}才の#{job}です."
end
#=> 太郎は["東京", 30, "プログラマー"]に住む才のです.
#   花子は["大阪", 20, "学生"]に住む才のです.

解決法

配列の要素を()で囲むことで、別々のブロック変数で扱えます

# (place, age, job)とする
people.each do |name, (place, age, job)|
  puts "#{name}#{place}に住む#{age}才の#{job}です."
end
#=> 太郎は東京に住む30才のプログラマーです.
#   花子は大阪に住む20才の学生です.

レシーバが配列でも同様にできます。

people = [
# [ name  , [place, age, job] ]
  ['太郎' , ['東京', 30, 'プログラマー'] ],
  ['花子' , ['大阪', 20, '学生'] ]
]

# レシーバが配列でもOK 
people.each do |name, (place, age, job)|
  puts "#{name}#{place}に住む#{age}才の#{job}です."
end
#=> 太郎は東京に住む30才のプログラマーです.
#   花子は大阪に住む20才の学生です.