Python使いがRubyを触るために理解するべきこと

# 概要

スクリプト言語的なものとしては、もっぱら`Python`を使っていたが、
このごろ`Ruby`を初めてややガッツリ触る機会があった。

すぐ慣れるだろうと甘くみていたら、予想以上にクセが強くて苦戦したので、
`Python`使いの視点から`Ruby`の特徴を簡単にメモっておきたいと思う。

まだまだ勉強不足なので網羅的な説明にはならないと思うが、
最低限これだけ把握すれば大体不都合なく`Ruby`を読み書きできるというポイントをまとめる。

# 省略文化

`Python`と似たようなものだろうと思っていた自分にまず面食らわせてきたのがこれ。
イカした特徴だと思うが、慣れないと大変。

## returnの省略

`return`は省略可。
例: ゲッターメソッド

```ruby
def name
  @name
end
```

メソッドの最後の行とは限らない。
例: case文

```ruby
def hoge(arg)
  case arg
  when A
    "Hoge"
  when B
    "Fuga"
  else
    "Foo"
  end
end
```

途中で強制的に`return`させる場合

```ruby
def hoge(arg)
  return "Hoge" if arg.nil?
  "Fuga"
end
```

`Ruby`のコーディング規約として、`return`の省略は行わない方が良いという文献もあった。

- https://shugo.net/ruby-codeconv/codeconv.html

`return`省略カッコいいけど、可読性とか保守性の面で気にする人も少なくなさそう。
チームや製品の文化に合わせることが大事そう。

## メソッドの括弧省略

引数ゼロのメソッドの宣言/コールは丸括弧を省略する。

```ruby
def hoge
  "Hoge"
end

p hoge
```

これによってゲッターメソッドが自然に書けるという、結構イカした仕様。

```ruby
class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end
end

person = Person.new("Alice")
p person.name
```

実際は自動プロパティ的な機能`attr`系があるので、そちらを使うことの方が多いかも。
そこら辺は後述。

コールの際は引数があってもカッコを省略することがある。
命令風に書きたい時に使われるのかな？
以下は全く同じ。

```ruby
hoge "Hoge", "Fuga"
hoge("Hoge", "Fuga")
```

## メソッドオブジェクト

さて、メソッドのカッコを省略できると聞いてまず思うのは、
**じゃあ関数ポインタどう書くの？**
ということ。
以下のようにシンボルを使って書き、コールには`call`メソッドを使う。

```ruby
def hoge(arg)
  p arg
end

fuga = method(:hoge)
fuga.call("hello")
```

この`method(symbol)`によって生成されるオブジェクトを`メソッドオブジェクト`とよぶ。
後述する`Procオブジェクト`との違いが非常に難しい。。。

## ディクショナリ(ハッシュ)のカッコ省略

最後の引数がハッシュの際はハッシュの波括弧を省略できる。
それだけなんだけど、、これがなんて恐ろしい、、、

```ruby
def hoge(hash)
  p hash["key1"]
end

hoge("key1" => "value1")
hoge({"key1" => "value1"})
hoge("key1" => "value1", "key2" => "value2")
hoge({"key1" => "value1", "key2" => "value2"})

# キーがシンボルの場合
hoge(key1: "value1")
hoge({key1: "value1"})
hoge(key1: "value1", key2: "value2")
hoge({key1: "value1", key2: "value2"})
```

ハッシュとシンボルについての説明は後述。
最初見た時ラムダ式でも渡しているのかと思ってた。。。

恐ろしいのは上例の後半の書き方。
この戦慄がお分かり頂けるだろうか、、、

```ruby
# キーワード引数
def hoge(hoge: "a", foo: "b")
  p hoge + foo
end

hoge(hoge: "a", foo: "b")

# ハッシュ引数
def hoge(**args)
  p args[:key1]
end

hoge(key1: "value1", key2: "value2")
```

`Ruby`の引数の受け渡しにおける壮大な思想の一面が見えた気がする、、

普通の引数も、キーワード引数も、ハッシュ引数も、
**渡す側からしたら区別がつかない** ということ。

区別する必要がない方が本質的だろ？
と`Ruby`に語りかけられているみたい、

他の人がどう考えているのかと思って少し調べたら、
とても分かりやすく引数についてまとめてくださっている記事があった。

- [https://qiita.com/raccy/items/1168c7e8849dedf70fa4](https://qiita.com/raccy/items/1168c7e8849dedf70fa4#%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0)

こういう仕様ならばハッシュ引数`**args`はなぜ必要なのかと疑問に思ったが、
多分以下のように特定のキーワード引数と分けて定義をするのに必要。

```ruby
def hoge(a, b: "v1", **args)
  # omit
end

# 特定のキーワード引数を分ける必要なければこれでいい
def hoge(a, hash)
  # omit
end
```

とにかく、この`最後の引数のハッシュは波括弧が省略可能`という仕様は、
非常によく考えられた深い仕様のように感じる。

# 命名規則

大体`Python`と同じかなと。

## 術語メソッド(predicate method)の`?`

bool返すメソッドは名前の末尾を`?`にして、
その分無理に疑問系にしない。
つまり、`is_`とか`has_`とかは基本つけない。

あくまでメソッド名の話。変数名の話ではない。

```ruby
# good
def connected?
  # omit
end

# bad
def is_connected?
  # omit
end
```

一見センス良く見えるが、このせいで以下のような不都合が出ているのかなとも。。。

```ruby
# 三項演算子: ?が2回続いて紛らわしい
a = hoge.connected? ? "a" : "b"

# null条件演算子: ?はメソッド名に使うからRubyでは&なのかな
hoge&.close
```

## 破壊的メソッドの`!`

破壊的メソッドとそうでないメソッドの両者がある場合は、
破壊的メソッドの方の末尾に`!`をつける。

これはセンスが良いと感じた。


```ruby
class Point
  def initialize(x, y)
    @x = x
    @y = y
  end

  def origin_symmetry
    Point.new(-@x, -@y)
  end

  def origin_symmetry!
    @x *= -1
    @y *= -1
  end
end
```

ただしこれはあくまで慣習であり、`!`がついていないから安心と思ってはいけない。

- [Ruby のメソッド名の ! の有無は破壊的／非破壊的を意味する，わけじゃない](https://qiita.com/scivola/items/237ffe27bff53b2b0a5a)

(↑コメントでご指摘頂きありがとうございました！)


# 制御構文

## unless

ifの反対。これを利用してできるだけ条件をシンプルにすることが求められる。

```ruby
# good
loop do
  break unless hoge
end

# bad
loop do
  break if !hoge
end
```

## ifとunlessの後置

すでに例で何度も出しているが、以下のように一行で書ける。

```ruby
# good
loop do
  break unless hoge
end

# bad
loop do
  unless hoge
    break
  end
end
```

`Python`に慣れているとあまりやりたくならないかもだが、
`Ruby`だと一行にできるときはそうした方が良いと考える人が多そうなイメージ。

## 繰り返し

- `continue`ではなくて`next`
- 繰り返しにおける`Python`のような`else`は無い。

- for-in(for-each)

```ruby
values.each do |v|
  p v
end
```

- 集合処理系

```ruby
# 写像
[1, 2, 3, 4].map {|v| 2 * v}
  # => [2, 4, 6, 8]

# 絞り込み
[1, 2, 3, 4].select {|v| v % 2 == 0}
  # => [2, 4]

[1, 2, 3, 4].reject {|v| v % 2 == 0}
  # => [1, 3]

[1, 2, 3, 4].find {|v| v % 2 == 0}
  # => 2
```

# ブロック, yield, Procオブジェクト, proc, lambda

モジュールと並んで最初最も難しい概念と思う。
以下参考にさせていただきました。

- [ブロック・Proc・lambda を理解する](https://qiita.com/k-penguin-sato/items/7f98335ef631ea5ce7ad)
- [ブロックと手続きオブジェクト](https://ie.u-ryukyu.ac.jp/~kono/software/s04/tutorial/Chapter=10.html)
- [ProcオブジェクトとMethodオブジェクト](https://vividcode.hatenadiary.org/entry/20100813/1281709854)

ここでは、自分なりに要点を整理しようと思います。

## ブロック

`do end`や`{}`で囲っているよく見るアレ。
`|a, b|`のようにして引数を受け取れる: ブロック変数

ブロック単体はメソッドに渡すために使う。
`Procオブジェクト`に包むことでオブジェクト化でき、無名関数のように扱える(後述)。

どちらも基本は同じ。
(厳密には引数に渡す時に挙動の違いがあったりする)

使い分けの目安としては、

- 一行で収まるときは`{}`、複数行は`do end`
- 後続でメソッドチェーンするときは`{}`

## ブロックとyield

`Python`の`yield`とは主従が逆！

- メソッドはデフォルトでブロックを1つ受け取ることができる
  - `method(args) block` という感じになっている
  - 通常はブロックを受け取ることについて明示する必要はない
  - `ブロック引数`を用いて明示的に受け取ることも一応できる(後述)
- 受け取ったブロックを`yield`で呼び出す
- `yield`で渡された値がブロック変数に来る(複数可能, 受け取らなくてもいい)

1行ずつ読んでyieldする例

```ruby
def read_lines
  io = FileIOMock.new
  loop do
    line = io.read_line
    break if line.nil?
    yield line
  end
end

read_lines {|line| p line}
```

んー、遅延評価とかメソッドチェーンとかやりにくい気がする、、、

<details>
<summary>動作確認用に作ったMock</summary>
<div>

```ruby
class FileIOMock
  def initialize
    @lines = [
      "hoge",
      "fuga",
      "foo"
    ]
    @i = 0
  end

  def read_line
    line = @lines[@i]
    @i += 1 unless line.nil?
    line
  end
end
```
</div>
</details>

## Procオブジェクト

- `Ruby`における無名関数のようなもの。
- `method(symbol)`で作った`メソッドオブジェクト`に似て非なる存在。
- `proc`と`lambda`の2種類に分けられる。

`メソッドオブジェクト`と対比させるなら、これは`ブロックオブジェクト`みたいなもの。
ブロックを直接メソッドに渡さず、オブジェクトとして扱いたい時に用いる。

## proc

2通りの生成方法

- `Proc.new (block)`
- `proc (block)`

```ruby
my_print_proc1 = Proc.new {|v| p "Hello #{v}"}
my_print_proc2 = proc {|v| p "Hello #{v}"}
```

## lambda

```ruby
my_print_lambda = lambda {|v| p "Hello #{v}"}
```

## ブロック引数

メソッドと受け渡しするブロックを、Procオブジェクトとして扱うためのもの。
意外と紛らわしいので、焦らずちゃんと理解した方が良い。

### 受け取り側

定義側で引数の最後に`&`をつけて`ブロック引数`を1つだけ定義することができる
すると、渡されたブロックを`Procオブジェクト`としてメソッド内で扱える。

先述した`yield`の例は、`yield`を使わずに以下のように書ける。

```ruby
def read_lines(&block)
  io = FileIOMock.new
  loop do
    line = io.read_line
    break if line.nil?
    block.call(line)
  end
end

read_lines {|line| p line}
```

**メソッドコール側に変化はない。**

### 渡す側

逆に、ブロックではなくて`Procオブジェクト`をメソッドに渡したい場合は、
コール側で引数の最後に`&`をつけてブロックとして渡すことができる。

```ruby
def read_lines
  io = FileIOMock.new
  loop do
    line = io.read_line
    break if line.nil?
    yield line
  end
end

my_print_proc2 = proc {|v| p "Hello #{v}"}
read_lines(&my_print_proc2)
```

**メソッド定義側に変化はない。**

ちなみに、この方法で`メソッドオブジェクト`も同様に渡すことができた。
(後述する`to_proc`メソッドが呼ばれてProcオブジェクトに変換されていると思われる)

### `to_proc`メソッドと`&`

(コメントで教えて頂き追記しました)

渡す側で`&`をつけて渡す際には、渡したオブジェクトの`to_proc`メソッドが呼ばれる。

元々Procオブジェクトを渡した際には何の意味もないが、
メソッドオブジェクトや、その他`to_proc`メソッドを実装しているオブジェクトに効果がある。

```ruby
class Hoge
  def to_proc
    proc {p "hoge"}
  end
end

def fuga
  yield
end

fuga(&Hoge.new)
  # => "hoge"
```

この仕様のおかげで、シンボルやハッシュも&で渡して利用できる。

ちなみに、`to_proc`はおそらく`proc`化するのでなくて、`Procオブジェクト`化するためのメソッド。
実際に`proc`になるのか`lambda`になるのかは実装次第と思われる。

### シンボルをProcオブジェクト化して、特定メソッドをコールさせる

シンボルの`to_proc`は、第一引数にそのメソッドのレシーバを受け取って自身をコールさせるようなProcオブジェクトになる。
これにより、シンボルを`&`で渡すことで`yield`される各要素の特定のメソッドをコールさせる記述をスッキリ書ける。


```ruby
["hoge", "", "fuga"].reject(&:empty?)
  # => ["hoge", "fuga"]

# これと同じということ
["hoge", "", "fuga"].reject {|v| v.empty?}
  # => ["hoge", "fuga"]
```

`:empty?.to_proc`は、`{|receiver| receiver.empty?}` のようなものになっていそう。

### 使い所

シンボルとかハッシュとか、Procオブジェクト化して使えるのは面白いし便利そう。

それ以外だと、慣れていない自分にとってはちょっと難しい。

紛らわしいが、普通に無名関数を渡したい文脈では、
`ブロック引数`なんて意識せず普通に以下のようにすればいい。

```ruby
def read_lines(line_process)
  io = FileIOMock.new
  loop do
    line = io.read_line
    break if line.nil?
    line_process.call(line)
  end
end

my_print_proc2 = proc {|v| p "Hello #{v}"}
read_lines(my_print_proc2)
```

デフォルトのブロックの受け渡しは1つしかできないので、
複数のコールバックを渡す必要がある場合にもこのような方法になるだろう。

~~ていうか、いつもこうすれば`ブロック引数`だとか`yield`だとかに混乱しなくて済むのでは？~~

そんなこと言ったら人類の進化は止まっちゃいますね。
せっかく綺麗に書ける仕組みがあるので、コールバックが1つの時は積極的に`yield`使おう。

そうなると、複数メソッドを跨いでコールバックを受け渡す必要がある場合に、
ブロック引数が必要になってくるはず。

両側のブロック引数の使い方を盛り込んだ例

```ruby
def read_lines(&block) # もらったブロックを子メソッドに跨がせたいのでprocとしてもらう
  io = FileIOMock.new
  loop do
    line = read_inner(io, &block) # 子メソッドのブロックへprocを渡す
    break if line.nil?
  end
end

def read_inner(io)
  line = io.read_line
  yield line unless line.nil?
  line
end

def line_process(time)
  case time
  when "morning"
    proc {|v| p "Good morning #{v}"}
  when "night"
    proc {|v| p "Good night #{v}"}
  else
    proc {|v| p "Hello #{v}"}
  end
end

read_lines(&line_process("morning")) # 渡す処理を動的に変更したいのでprocとして渡したい
```

# 例外処理

基本形

```ruby
begin
rescue => e
ensure
end
```

メソッド全体にかける場合は`begin`と`end`は省略できる

```ruby
def hoge
  p "main process"
  raise "just for test"
rescue => e
  p "error occurred: #{e.message}"
ensure
  p "this line is always called"
end
```

特定の例外を捕捉し`retry`する例
(`retry`は`rescue`句の中でしか使えない)

```ruby
count = 0
begin
  case count
  when 0
    raise IOError, "fuga"
  when 1
    raise "foo"
  else
    p "success!"
  end
rescue IOError => e
  p e
  count += 1
  retry
rescue => e
  p e
  count += 1
  retry
end
```

tips

- `raise`には例外クラスとメッセージを別々に渡す
    - 次のように例外インスタンスを渡すのは良くないらしい
        - `raise IOError.new("msg")`
    - 理由は前者の方が実はbacktraceに関する第三引数が省略可能で隠れていることにあるらしい
    - ではメッセージだけ渡すケースについてはどう考えれば？？？
        - ちなみに例外クラスとしては自動で`RuntimeError`になるらしい
- `Exception`クラスは`rescue`してはダメ
    - `rescue`して良い最も標準的なクラスは`StandardError`
        - 実は `rescue => e` = `rescue StandardError => e`
- `ensure`句の中で`return`してはダメ
    - 例外が潰されてしまう
    - 実は`ensure`句の中では`return`省略は無効。明示的に`return`を書かなければ大丈夫。

参考: https://techracho.bpsinc.jp/hachi8833/2017_03_21/37192

# クラス

## インスタンス変数

- `@`を先頭につける
- クラス外からは参照できない

## クラスメソッド、クラス変数、クラスインスタンス変数

static系。

- クラスメソッド: 先頭に`self.`をつける
  - `クラス名.`でも良いが、冗長で好ましくないだろう
- クラス変数: 先頭に`@@`をつける
- クラスインスタンス変数: staticに宣言したインスタンス変数
  - クラスもClassクラスのインスタンスらしい、、
  - クラス直下やクラスメソッド内でインスタンス変数を定義するとこれになるっぽい

staticなメンバ変数が普通に使えれば満足なんだけど、、
クラス変数とクラスインスタンス変数って、、

実はクラス変数は全てのサブクラスと共有される仕様らしい(子クラスに値を書き換えられる？)。
一方でクラスインスタンス変数は継承とは無関係。

可読性を考えたらできるだけクラス変数の方を使いたいように思うが、
確かに全てのサブクラスで共有っていうのも嫌だなあ。

## クラス直下のローカル変数宣言とか処理とか

`Python`に慣れている人なら、以下のように思うだろう。

クラス変数は先頭に`@@`つけるならば、
ローカル変数をクラス直下に宣言したら何が起こるのか？
`Python`はクラス直下に宣言した変数がクラス変数になるし。

クラス直下のローカル変数宣言や処理はクラスのロード時に走るだけで、
特に変数はクラスに紐付かずに破棄される。

クラスのロード時の処理を普通に書けるのは便利かも。
`Python`もできたっけ？？

## 定数

- アルファベット大文字 ([A-Z]) で始まる識別子は定数
- 定数は名前空間上(module, class上)に定義し、そこに保持される
  - メソッド内では定義できない
  - 外部からは`::`でアクセス
  - 内部からはインスタンスメソッド、クラスメソッドの双方から直接アクセスできる

## 定数、変数、メソッド全部のせ

```ruby
class Hoge
  # クラスロード時のローカル変数。ロード後破棄される。
  local_var = "local var" 
  # クラスロード時に一度だけ実行される
  p local_var 

  # 定数。名前空間上に保持される。
  # 外部からはHoge::CONSTANT_VARのようにアクセス
  # 内部からは直接アクセス可能
  CONSTANT_VAR = "constant var" 

  # クラス変数
  @@class_var = "class var"

  # クラスインスタンス変数
  @class_instance_var = "class instance var"

  # クラスメソッド
  def self.class_method
    p "start class method"
    p @@class_var
    p @class_instance_var
    p CONSTANT_VAR
    p "end class method"
  end

  def initialize
    #インスタンス変数
    @instance_var = "instance var"
  end

  # インスタンスメソッド
  def instance_method
    p "start instance method"
    p @instance_var
    p CONSTANT_VAR
    p "end instance method"
  end
end

Hoge.class_method
Hoge.new.instance_method
p Hoge::CONSTANT_VAR

  # => "local var"
  # => "start class method"
  # => "class var"
  # => "class instance var"
  # => "constant var"
  # => "end class method"
  # => "start instance method"
  # => "instance var"
  # => "constant var"
  # => "end instance method"
  # => "constant var"
```

## アクセサ

自動プロパティ。

```ruby
class Hoge
  attr_accessor :rw # getter, setter
  attr_reader :r # only getter
  attr_writer :w # only setter

  def initialize(a, b, c)
    @rw = a
    @r = b
    @w = c
  end
end
```

## アクセス修飾子

メソッドはデフォルトでpublic。
privateキーワード以降が全部privateになる(wow!)

以下は fuga, hoo がprivateメソッドになる。

```ruby
class Hoge
  def hoge
  end

  private

  def fuga
  end

  def foo
  end
end
```

~~可読性、、保守性、、どうしてこうなった、、~~

(コメントでご指摘いただきました！
クラスがシンプルならばこれが便利と考える方も多そうです。)

Ruby 2.1 からは普通に以下のようにメソッド毎に書けるらしい。

```ruby
class Hoge
  # 言わずもがなpublic
  def hoge
  end

  # これだけprivate
  private def fuga
  end

  # これはpublic
  def foo
  end
end
```

~~絶対これを徹底した方が良いと思うのだけれども、
なぜかこうしていないコードをよく見る気がする。~~

(コメントを頂いたので以下追記)

これについては考え方が分かれそうです。
確かにクラスがシンプルであれば、まとめてprivateにしてしまう旧来のやり方も便利かもしれません。
自分は今まで当たり前のようにメソッド毎にprivateを付与してきたので、ちょっと慣れないですが、
チームや製品の文化に合わせるのが良さそうですね。

### Rubyのprivateは実は曲者

privateメソッドは子クラスから呼び出せる(後述)。
`Ruby`のprivateは **レシーバから呼び出せない** という仕様らしい(ただし`self.`からは可能)。
なるほど、確かにそれなら一見privateっぽい挙動に見えるわけだ。

### その他

細かい癖のある仕様が多くてまとめきれないので、ざっくり

- privateの時点で子クラスから呼べるというのに、protectedがあるらしい
- クラスメソッドをprivateにするには`private_class_method`なるものでシンボル指定しないといけないらしい

## interface, abstract

ない。`Python`と同じ。

## オーバライド

- コンストラクタ、アクセサも含めインスタンスメソッドは全て継承されるし、オーバライドできる
  - ただ同名で再定義するだけ
  - `super`で親メソッドをコールできる
- 親のprivateメソッドも使える
- クラスメソッドも継承される
- クラス変数は共有されるので注意が必要
- クラスインスタンス変数は全く継承されない
- 定数は継承される、オーバーライドもできる

```ruby
class Person
  def initialize(name)
    @name = name
  end

  def greet
    say "こんにちは。"
  end

  private

  def say(msg)
    p "#{@name}: #{msg}"
  end
end

class CheerfulPerson < Person
  def greet
    super
    say "今日もいい天気ですね。"
  end
end

class SilentPerson < Person
  def greet
    say "...。"
  end
end

Person.new("Alice").greet
CheerfulPerson.new("Bob").greet
SilentPerson.new("Chris").greet

  # => "Alice: こんにちは。"
  # => "Bob: こんにちは。"
  # => "Bob: 今日もいい天気ですね。"
  # => "Chris: ...。"
```

## 特異メソッド

インスタンスに対して定義したメソッド。

```ruby
class Hoge
end

hoge = Hoge.new
def hoge.special
  p "hello"
end

hoge.special
  # => "hello"
```

インスタンスに紐づくメソッドのように見えるが、
やっぱりメソッドは特定のクラスに紐づかないといけないということで、
この時には内部で専用のクラスを自動生成しているらしい。
そのクラスのことを特異クラスと呼ぶ。

後述するmixinをextendする際に特異メソッドを意識する。

# モジュール

ブロックと並んで最初最も難しい概念の1つと思う。

## 名前空間としてのモジュール

これは簡単。
入れ子になったクラスも名前空間を形成する。

```ruby
module Hoge
  class Fuga
    module Foo
      class Poo
        def poo
          p "poo"
        end
      end
    end
  end
end

Hoge::Fuga::Foo::Poo.new.poo
  # => "poo"
```

## staticクラスとしてのモジュール

モジュールは実はstaticクラス、つまりインスタンス化できないクラスのような性質がある。

- module内でクラスメソッドを定義することで、外部から参照させられる
- 定数は名前空間上に公開される

```ruby
module A
  CONST_VAR = "constant var"

  def self.hoge
    "hello"
  end
end

p A::CONST_VAR
  # => "constant var"
p A.hoge
  # => "hello"
```

一応`module_function`というmoduleのインスタンスメソッドを公開する方法もあるが、
mixinをマスターした上級者向けの話と思う。

## mixinとしてのモジュール

moduleがインスタンス化できないクラスならば、
module内のインスタンスメソッドは何に使えるのか？

その答えが、mixin。

`Python`は多重継承でmixin可能だが、`Ruby`は多重継承できない。
そのため`Ruby`ではモジュールを使ってmixinを実現する。

モジュールをmixinする方法は、下記の3種類。

- include
  - 自身の親クラスにモジュールを挿入する
  - モジュールを継承するイメージ
- prepend
  - includeの逆で、モジュールに自身を継承させるイメージ
  - 自クラスの実体がモジュールにスイッチし、その親クラス側に自クラスがくる感じ
- extend
  - モジュールのインスタンスメソッドをselfの特異メソッドとして追加する
  - クラスに対してextendした場合はクラスメソッドとして追加される
  - インスタンスに対してextendした場合はインスタンスメソッドとして追加される

なんとモジュールがモジュールをmixinすることもある。

イルカとサメという異なる継承関係のクラスに、「泳ぐ」という共通処理をmixinする例。
(個人的にどこかで読んだイルカとサメのmixinの例がわかりやすくて好きです)

```ruby
class Mammal
end

class Fish
end

module Swimmer
  def swim
    p "swim!"
  end
end

class Dolphin < Mammal
  include Swimmer

  def swim
    super
    p "cute!"
  end
end

class Shark < Fish
  include Swimmer

  def swim
    super
    p "scary!"
  end
end

Dolphin.new.swim
  # => "swim!"
  # => "cute!"
Shark.new.swim
  # => "swim!"
  # => "scary!"
```

`include`を使って親クラスとしてSwimmerモジュールを挿入しているので、
オーバーライドして動作を拡張して利用できる。
もちろんオーバーライドせずそのまま利用することもできる。

(@scivolaさんに`extend`の活用例を教えて頂いたので、以下追記)

モジュールはインスタンス化できないが、
以下のように`extend`を`Object`クラスのインスタンスに使うことで、それっぽいことができる。

```ruby
module ModuleA
  def hoge
    p "hoge"
  end
end

obj = Object.new
obj.extend ModuleA
obj.hoge
```

## モジュールでsuper!?

保守性、可読性の観点で疑問は残るが、mixinはやろうと思えば色々な使い方ができてしまう。
コードを読めるようになるために慣れる必要がありそう。

module内でインスタンス変数を使ってしまう例

```ruby
module Fuga
  def introduce
    p "My name is #{@name}"
  end
end

class Hoge
  include Fuga

  def initialize(name)
    @name = name
  end
end

Hoge.new("Alice").introduce
  # => "My name is Alice"
```

mixin先に特定のインスタンス変数があることを前提としてしまっている。
個人的には良くないと思う。

以下はmodule内のsuperのヤバイ例

```ruby
class Poo
  def hoge
    p "poo"
  end
end

module Foo
  def hoge
    super
    p "foo"
  end
end

module Fuga
  include Foo

  def hoge
    super
    p "fuga"
  end
end

class Hoge < Poo
  include Fuga

  def hoge
    super
    p "hoge"
  end
end

Hoge.new.hoge
  # => "poo"
  # => "foo"
  # => "fuga"
  # => "hoge"
```

最終的に継承関係が`Hoge -> Fuga -> Foo -> Poo`のようになる。
includeしたモジュールのsuperは、元々の親クラスを呼び出しにくわけだが、
モジュールがモジュールをincludeしていることもありえて、こうなるとかなり厄介。

# その他細かいポイント

## %記法

以下の記事が参考になりました

- [Rubyで%記法（パーセント記法）を使う](https://qiita.com/mogulla3/items/46bb876391be07921743)

## インターポレーション

```ruby
name = "Alice"
p "Hello #{name}, how are you?"
  # => "Hello Alice, how are you?"
```

## シンボルと文字列

`:`で始めるとシンボルになり、次の特徴を持つ。

- シンボルは、任意の文字列と1対1対応する
- 同じシンボルは必ず同じオブジェクト
- 中身は整数

文字列というよりはEnumに近い。
その性質上ハッシュのキーによく用いられる。

文字列とシンボルの変換

```ruby
:hoge.to_s
  # => "hoge"

"hoge".to_sym
  # => :hoge
```

## ハッシュ

普通のハッシュ。

```ruby
h = {"key1" => "hoge", "key2" => "fuga"}
f["key3"] = "foo"
```

シンボルがキーの場合は特別な記法がある。

```ruby
h = {key1: "hoge", key2: "fuga"}
h[:key3] = "foo"
h[:key1]
  # => "hoge"
h["key1"]
  # => nil
```

## nil関連

リストで存在しないインデックスを指定した時や、
ハッシュで存在しないキーを指定した時は、
例外は発生せず、nilを返す。

## 対話型の起動

`irb`コマンド

# 終わりに

思ったよりも大変だったが、面白い言語だと思った。

慣れてしまえば`Python`と同じくらい便利に使えそう。

`map`とか`select`といった集合処理系が強そうなのがとても良い。
`Python`も見習ってほしい(リスト内包表記使いにくい)。

一方で`Ruby`の`yield`の仕様は気になった。
`Python`のようにジェネレータを返せる方が遅延評価とか便利なんじゃないだろうか。