「プロを目指す人のためのRuby入門」を読んだので。


[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774193976) を読んだので、個人的に気になったことなどをまとめてます。

## 学んだこと
### 式展開(`#{}`)を使った時は、自動的に`to_i`が呼び出されるので、文字列に変換する必要はない。

```ruby
number = 3
"Number is #{number}" #=> Number is 3
```

### メソッドの戻り値の指定に`return`は使わない。  
最後に評価された式がメソッドの戻り値になる。
`return`はメソッドを途中で脱出する場合に使われる。

```ruby
def greet(country)
  if country == 'japan'
    `こんにちは`
  else
    `hello`
  end
end
greet('japan') #=> "こんにちは"
greet('usa')   #=> "hello"
```

### Rubyの繰り返し処理は`for`ではなく`each`を使う。

```ruby
numbers = [1, 2, 3, 4]
sum = 0

# NG：forは使わない
for number in numbers
   sum += number 
end

# OK：eachを使う
numbers.each do |number|
   sum += number
end

sum #=> 10
```

### `join`はPythonと逆。
普段Pythonを書いているため、間違えそうなのでメモ。

```ruby:Ruby
chars = ['a', 'b', 'c']
chars.join('-') #=> "a-b-c"
```

```python:Python
chars = ['a', 'b', 'c']
'-'.join(chars) #=> "a-b-c"
```

### シンボル
シンボルとは任意の文字列と1対1に対応するオブジェクト。  
文字列と比べて処理が高速。 
そのため、ハッシュのキーや定数に使用する。

```ruby
# 通常の定数
const = "constant"
# シンボルを使った定数
const = :constant

# 通常のハッシュ
hash = {"key1" => "value1", "key2" => "value2"}
# シンボルを使ったハッシュ
hash = {:key1 => "value1", :key2 => "value2"}
# ハッシュのキーにシンボルを使う場合、こう書ける
hash = {key1: "value1", key2: "value2"}
```

### ブロック
ブロックとはメソッドの引数として渡せる処理のかたまりのこと。
`do ... end`, `{ ... }`の箇所がブロックにあたる。
改行を含む長いブロックは`do ... end`, 1行で書けるブロックは`{ ... }`を使うと良い。

```ruby
numbers = [1, 2, 3, 4]
sum = 0
numbers.each do |n|
  sum += n
end
sum #=> 10

# 上の処理と同じ
numbers = [1, 2, 3, 4]
sum = 0
numbers.each { |n| sum += n }
sum #=> 10
```

### ブロックに渡すメソッドの省略

以下条件の時、`&:メソッド名`で記述を省略できる。

1. ブロックパラメータがひとつ
1. ブロック内で読み出すメソッドに引数がない
1. ブロックパラメータに対してメソッドを1回呼び出す以外の処理がない
```ruby
['ruby', 'java', 'python'].map { |s| s.upcase }
#=> ["RUBY", ""JAVA, "PYTHON"]

# 上と同じ処理内容
['ruby', 'java', 'python'].map(&:upcase)
```

### クラスメソッドの定義
```ruby
class クラス名
  def self.クラスメソッド
    # 処理
  end
end

# 以下書き方も可
# 毎回selfを記述しなくてよいので、複数定義する場合はこっちが楽
class クラス名
  class << self
    def クラスメソッド1
      # 処理
    end
    def クラスメソッド2
      # 処理
    end
  end
end
```

### モジュール

モジュールをクラスにincludeして機能を追加することをミックスインという。
ミックスインすることで継承関係を気にすることなく機能を追加できる。
Rubyは単一継承を採用しているが、ミックスインを利用することで多重継承に似た仕組みを実現している。

```ruby
module Loggable
  def log(text)
    puts "[LOG] #{text}"
  end
end

class Product
  include Loggable

  def title
    log 'title is called.'
    'A great movie'
   end
end

product = Product.new
product.title
```

### ブロックを引数に受け取る
ブロックを引数として受け取る場合、引数に`&`を付ける必要がある。

```ruby
def sample_method(string, &block)
  puts '処理開始'
  block.call(string)
end

sample_method('foo') { |s| s.upcase }
#=> 処理開始
#=> "FOO"
```

### Procオブジェクト
Procオブジェクトとはブロックをオブジェクト化したもの。

```ruby
def sample_method(string, &block)
  puts '処理開始'
  block.call(string)
end

proc_upcase = Proc.new { |s| s.upcase }

sample_method('foo', &proc_upcase)
#=> 処理開始
#=> "FOO"
```

## 良かったところ
章ごと例題プログラムを作成する際、テスト駆動開発で進むため、自然とテストコードの書き方や手順を学べた。
一般的な入門書よりワンランク深ぼった内容が書かれているので、Rubyの理解度を深めることができた。

## 難しかったこと
Procオブジェクトの使いどころの説明でActiveRecordのスコープで使うとのことだが、Railsの理解が浅いのであまりピンとこなかった。

## 参考文献
https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774193976