Ryo5smileの技術ブログ

学んだこと

【8月2週目】「プロを目指す人のためのRuby入門」を読んで(1/2)

プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)

はじめに

Ruby勉強するならチェリー本(通称)!」と色んなところで言われているくらい有名な本で、ある程度基礎を学んだ後に読むのがおすすめな本らしいです。著者の伊藤淳一さんは元バンドマンだそうでそこからIT業界に転身した異色の経歴の持ち主。私はweb系エンジニアになるまで読んだことがなかったですが、ここ最近実務で基礎力が身に付いていないと痛感したため読み始めました。

サブタイトルの「言語使用からテスト駆動開発デバッグ技法まで」とある通り、広範囲をカバーしている内容となっています。この記事ではその中から「この部分の内容を忘れたくない!」点をいくつかサンプルコードも交えながら書いていこうと思います。

配列や繰り返し処理

配列は頻繁に扱うオブジェクトで、特に繰り返し処理と組み合わせて使うことが多いです。扱うデータ量が多い時ほど使う印象があります。しかしあまり詳しく深掘りをしてこなかったため重点的に読みました。

配列

配列はオブジェクトの一種で複数のデータをまとめて入れることができます。配列内のデータは順番に並んでおり、データごとに番号が割り当てられてそれを指定することで取り出すことができます。

配列内の特定の位置にあるデータを削除する方法

delete_atを使う

# 配列を作成し、文字列a,b,cを入れる
array = ["a","b","c"]
# 1番目の要素を削除する
array.delete_at(0)
puts array  # => ["b","c"]

条件を指定して配列内のデータを削除する

delete_ifを使う

array = ["a","b","c","a","b","c"]
# 配列から特定の文字列を削除する
array.delete_if do |n|
   n = "a"
end
puts array # => ["b","c","b","c"]

delete_ifは繰り返しでよく使われるeachメソッドと同じように、配列内のデータ一つ一つを順番に取り出します。そしてそのデータをブロックに渡して処理を行います。 配列内のデータを消す場面では特に条件を指定して消したい場合が結構多いと思うので、delete_ifは必ず押さえておきたいです。

ブロックを使う配列のメソッド

配列で使うメソッドはeachやdelete_ifの他に色々なメソッドが用意されています。

map / collect

mapメソッドは配列内の各データに対してブロックを評価した後に新しい配列に返します。eachやdelete_ifは同じ配列に戻り値を入れていましたが、mapメソッドは新たな配列を作成し、そこに戻り値が入ります。例えばそれぞれの金額に対して消費税を加算する処理を書きたい場合、mapメソッドでは以下のようになります。

prices = [100,250,500]
tax_included_price = prices.map{ |n| n * 1.1}
puts tax_included_price # => [110, 275, 550]

このようにそれぞれの金額に対して10%の消費税が加算された金額が作成された配列に入りました。 まだ実務ではmapを使ったことがないですが、このコードのように繰り返した後に新しい配列を作成して値を入れるという処理は、「元々の配列のデータを書き換えたくない」場合などに使うのかなと想像しています。あとは空の配列にループした結果を入れたい時などに使われそうな印象です。元の配列があってその配列をもとに処理を複数行いたい場合は便利だと思います。

select / reject

selectはmapのように新たな配列に値を入れるのは同じですが、異なる点は「各データに対してブロックを評価し、その戻り値が真(true)のデータを集めた配列を返す」メソッドです。

prices = [100, 250,500]
and_over_price = prices.select{ |n| n >= 400}
puts and_over_price # => [500]

このコードでは400以上のデータだけを配列に集める処理がされています。条件結果がtrueのデータの500だけが配列に入っています。

rejectはselectの逆で「各データに対してブロックを評価し、その戻り値が偽(false)のデータを集めた配列を返す」メソッドになっています。

prices = [100, 250,500]
and_over_price = prices.reject{ |n| n >= 400}
puts and_over_price # => [100,250]

このように400以上のデータを除外する処理になっています。余談ですがこの場合はselectメソッドを使い条件を>= 400から<= 400に変えてもいいと思います。

文字列の配列の様々な作り方

[]で作る

["Sunday","Monday", "Tuesday"] # => ["Sunday","Monday", "Tuesday"] 

%wと!で作る

%w!Sunday Monday Tuesday! => ["Sunday","Monday", "Tuesday"] 

%wと()で作る

%w(Sunday Monday Tuesday) => ["Sunday","Monday", "Tuesday"] 
# 以下のように改行も認識される
%w(
 Sunday 
 Monday 
 Tuesday
)
=> ["Sunday","Monday", "Tuesday"] 

私は一番目以外の書き方を知りませんでしたが、どういう時にどの書き方を使うかはチーム内で統一したほうが良さそうです。(%wはコードがスッキリしていて見るのも書くのも楽だし個人的にはこれを使っていきたい)

さまざまな繰り返し処理

times

処理を実行したい回数を指定することができるメソッドです。その為配列は使いませんが、「◯回処理を実行したい」という時に便利なメソッドです。

total = 0
10.times { |n| total += n }
puts total # => 45

while文

while文は指定した条件式が真(true)の間、繰り返し実行されます。

p = 1
while p <= 5
  puts p
  p += 1
end

until文

untilは指定した条件式が偽(false)の間、繰り返し実行されます。

p = 1
until p >= 5
  puts p
  p += 1
end

おわりに

配列や繰り返しの処理について結構多いボリュームで書かれていたのが驚きでした。入門書ではあまり深掘りされていなかったので、やはりある程度基礎を固めた上で取り組むにはうってつけの本だと感じました。だからこそ「もっと早く読んでればなー」とも思いました。 次回は正規表現やクラスについての内容を予定しています。