Ruby初心者が「プロを目指す人のためのRuby入門」を6週間かけて写経して学んだこと

## Okinawa.rbアドベントカレンダー 2018
この記事は[Okinawa.rb Advent Calendar 2018](https://qiita.com/advent-calendar/2018/okinawarb)の10日目の記事です。
昨日は @saboyutaka さんの未経験から[Ruby on Railsを学んで仕事につなげるまでの1000時間メニュー](https://qiita.com/saboyutaka/items/1a8c40e105e93ac6856a)でした。

## はじめに
内定先の会社の入社前課題の一環として、[プロを目指す人のためのRuby入門](https://amzn.to/2QFXVvy)いわゆるチェリー本を写経しました。
読んだことはあったのですが、改めて写経してみると学びが多かったです。
写経といっても文書を全てを書き写す訳ではありません。
読んでいて実行結果をイメージできないコードがあったら打ち込んで実行して確認していくという感じです（写経のやり方はこの記事の最後にリンクを貼りました）。
時間はかかりますが、ただ読むよりも何倍も学習効果が高いと思います。
特に僕のように読み飛ばし癖のある人には良いと思います。
この本の序文にも書かれているのですが、初心者向けというより、他の書籍やサービスで入門した次のステップの本という感じです。
2章が始まる18ページから始めて、付録の444ページまで週平均66ページくらい写経しました。
5章くらいまではすぐに進んで6~8章あたりが正規表現やクラス設計やモジュールなどで難しくなってきます（正規表現が苦手な人は6章だけでも写経オススメです！）。

## 概要
多少理解に時間を要した概念や書籍の中で繰り返し出てきた部分をピックアップして紹介していきます。
※　()内の数字は書籍での章番号を表しています。

## %記法で文字列を作る(2.8.2)
* %q!!は'　'と同じ

```ruby
puts %q!Hello!
# => Hello
puts "Hello"
# => Hello
```

* %Q!!と%!!は"　"と同じ

```ruby
puts %Q!Hello!
# => Hello
puts %!Hello!
# => Hello
puts "Hello"
# => Hello
```
%記法はProgateや初心者向けの本だけでは、あまり出てこないので慣れるのに時間かかりました。
記号が少ないのがRubyの好きなところだったんですが、文字列の中でダブルクォートを使う時にエスケープする手間が省けるなどメリットはあるなと思いました。
※　区切り文字は!以外にも?や^など任意の記号を使えます。

## ブロックを使うメソッドへの&:メソッド名での引数渡し(4.4.5)

このコードを、

```ruby
["apple", "orange", "banana"].map {|s| s.upcase}
# => ["APPLE", "ORANGE", "BANANA"]
```

こう書き換えます。

```ruby
["apple", "orange", "banana"].map(&:upcase)
# => ["APPLE", "ORANGE", "BANANA"]
```

これはブロックを使うメソッドを簡潔に書く書き方で、以下の3つの条件が揃った時に使えます。
1. ブロック引数が**1**つのとき。今回は|s|のみ。
2. ブロック内で呼び出されるメソッドに引数がない(**0**)とき。今回はupcaseに引数はない。
3. ブロックの中でブロック引数に1回メソッドを呼び出すだけの処理になっているとき。今回はmapの中でupcaseが**1**回だけ呼ばれる。

&:メソッド名←という書き方になるんですが、
　ブロック引数である|s|とこれにメソッドを呼び出すときのs.が省略されて{}が()になります。
書籍の中で何度も出てくるので、しっかり確認しておきましょう。

## **でハッシュを展開させる(5.6.2)
以下のようなハッシュがあったとき、

```ruby
animals = { cat: "neko", dog: "inu" }
```
このハッシュを別のハッシュにいれて、`**`をつけてみます。

```ruby
{ bird: "tori", **animals }
```
こうなります。

```ruby
{:bird=>"tori", :cat=>"neko", :dog=>"inu"}
```
ちなみに、これは`merge`メソッド も同じことができます。

```ruby
{ bird: "tori" }.merge(animals)
# => {:bird=>"tori ", :cat=>"neko", :dog=>"inu"}
```

## !!を使った真偽値の型変換
確実にtrueまたはfalseを返すようにするためのRubyのイディオムとして有名なものがあります。

```ruby
def animals_exist?
  animals = find_animals
  if animals
    true
  else
    false
  end 
end
```

これは、以下のようにシュッと書けます。

```ruby
def animals_exist?
  !!find_animals
end
```



## 正規表現(6.2.2)
ここでは、必ず（絶対に！）書籍でも紹介される下記の参考資料に目を通してから読み進めましょう。

[初心者歓迎！手と目で覚える正規表現入門・その１「さまざまな形式の電話番号を検索しよう」](https://qiita.com/jnchito/items/893c887fbf19e17d3ff9)

[初心者歓迎！手と目で覚える正規表現入門・その２「微妙な違いを許容しつつ置換しよう」](https://qiita.com/jnchito/items/64c3fdc53766ac6f2008)

[初心者歓迎！手と目で覚える正規表現入門・その３「空白文字を自由自在に操ろう」](https://qiita.com/jnchito/items/6f0c885c1c4929092578)

[初心者歓迎！手と目で覚える正規表現入門・その４（最終回）「中級者テクニックをマスターしよう」](https://qiita.com/jnchito/items/b0839f4f4651c29da408)

読んだだけの時は全く頭に入らなかった正規表現も、写経すると最低限は覚えられました。

正規表現はこう書く（超基本）。

```ruby
/正規表現/
```

\dは1個の半角文字。

```ruby
/\d/
```

\dに{n}をつけると個数も指定できる。
* 半角文字を3個指定

```ruby
/\d{3}/
```

[]は「または」を示す。
* abcのどれか1文字

```ruby
/\d[abc]/
```
こんなのは正規表現のほんの少しに過ぎません。
しかし、Rubyの正規表現全くわからない!という人は参考リンクを読んで、この6章をやるだけでもかなり学べると思います。

## (追記)ぼっち演算子(Safe Navigation Operator) &.
このように使います。

```
レシーバ&.メソッド
```

&.は.の仲間で、メソッドの呼び出し形式の1種です。
この演算子を使うと、メソッドのレシーバがnilであっても、メソッド呼び出し時にnilが返されます。
つまり、エラーになりません。
メソッドが定義されていない場合には、NoMethodErrorが発生します。


## さいごに

記号が苦手な気がしました。
これからチェリー本で勉強する人の参考になればと思います。
ボリュームはありますが、その分解説の文章とサンプルコードが多いので、Ruby入門してRailsやるまでの間の一冊には最適な教材だと思います。
写経を終えて僕はRubyに多少自信が持てるようになりました。
チェリー本写経オススメです！

写経のやり方は自分のブログに書きました。
https://kousy.hatenablog.com/entry/2018/10/15/155505
写経用に使ったリポジトリはこちらです。
https://github.com/kos31de/RubyForPro
写経中に書いた記事は以下です。
minitestの依存関係(?)問題をbundlerで解決する
https://qiita.com/kos31de/items/6ae22f0a862910221bb0
※誤り等ありましたら、コメント下さい！