（これから覚えるPG向け）Rubyでびっくりしないためのざっくり解説

# Rubyでびっくりしないために

別な言語を覚える時のハードルの１つに、その言語の記法だったり慣用だったりがある。
Rubyのそういった特徴の私的メモ。


## 基本

### 言語の特徴

- スクリプト言語でオブジェクト指向言語。
    - ほぼ全てがオブジェクトで構成されている。
- イテレーション処理とクロージャ処理に長けていて、データの集合をDBと組み合わせて扱うのが得意。
    - 現代のWeb系サービス向け（Railsの影響が大きいかな）。
- 書き方は結構ゆるめで、敷居が低い。
    - ブロックでカッコを使わないなど、多少癖はある。
- 全てがオブジェクトなので型はないと思って良い。[動的型付け言語](https://ja.wikipedia.org/wiki/%E5%8B%95%E7%9A%84%E5%9E%8B%E4%BB%98%E3%81%91)。
- Ruby といえば、 Ruby on Rails というくらい、Railsとは切っても切り離せない関係。
    - なので、初心者がRailsから入ると、あるクラスやメソッドが、Rails由来なのか言語標準なのかを判断するのに苦労はする。（気にしないでググる、って手もある）
- `irb`という、強力な[コマンドラインインタプリタ](http://docs.ruby-lang.org/ja/2.0.0/library/irb.html)がある。
- モジュールは豊富。導入も簡単。（Bundlerという仕組みが用意されている）
- ドキュメントはネット上にも豊富。
    - だけどなぜか探しにくい。いろいろな人が色々な所に書いていて、どれが**最新で正しいか**判断しにくい。GoogleやQiitaで上位にランクしている記事が数年前のバージョンを対象とした古い記事だったりとか。Rubyに限らないけど、人口に膾炙されているだけに、そういう傾向が目立つ気がする。
    - 「設定より規約」の影響なのか、「当然知っているだろうから（知っている人が対象だから）説明しないよ。あえてね」っぽいのが多い印象。
    - なので、場合によってはソースを見た方が早い、ってこともある。

### 文法

C由来の言語のいいところを取りつつ、`nil`、`;`を使わない、制御構造も`{}`の代わりに`do ~ end`など、独自の設計思想がある。逆に言えば、`;`や`{}`で区切ったり囲ったりする文法に馴染んだ人には、慣れるまで少し時間が必要かも。

- JavaやJavascriptのNULLにあたるものは、`nil`（ニル）。LISPからの影響かしらん。
- `nil`と`false`以外は全て`true`。`0`も`true`。`""`も`true`。
    - なお、`undefined` 値はない。
- 変数宣言は要らない。
- 全ての変数はオブジェクトへの参照。そのため関数への値渡しもない。
- 行末のセミコロンは要らない。明示的に`;`を入れて式を区切ることは可能。
    - セミコロンが要らないために、逆に`¥`で明示的に行を継続させる方法も用意されている。例えば、メソッドの引数を改行後に与えてしまうとRubyは引数が無いと判断してしまう。こういう場合、`()`で囲むか、`¥`を使う。

```rb
      somearray.push        # <- ()で囲むか、`¥`で行が継続していることの明示が必要
        new_array_member
```

- `:任意の文字列`で*シンボル*を表す。ラベルのようなもの。内部的に番号管理されるので、速度面やメモリ面での[利点がある](http://docs.ruby-lang.org/ja/2.0.0/class/Symbol.html)。なによりコードの可読性や文脈が向上するのがありがたい。
- コメントはPerlと同様`#`。`#`以降がコメントとみなされる。C/C++、Javascriptのような複数行コメント `/* */` はない。
 - ブロックコメントがあり、`=begin` ~ `=end`。"begin"は省略できない。
- `#coding: utf-8`として（[マジックコメント](http://docs.ruby-lang.org/ja/2.0.0/doc/spec=2fm17n.html#script_encoding)）、エンコードを指定して処理系に伝える。ソースコードの1行目ないしは2行目（シェバンがある場合）に書く。


### 式

- 全てが式。`if`なども式。式なので結果が発生する。
    - `if`のような他言語の制御文にあたるものを式として意識する必要は、普段は持たなくて良い。
        - メソッドの返り値だけ気をつける。
    - メソッドの返り値は`return`で明示的に返すこともできるが、Perlのように、最後の演算結果が暗黙的に返り値となる。
- 代入式で一度に複数個への代入が可能。（`a,b = 1,2`）
- 三項演算子（`A ? X : Y`）は、それぞれの記号の前後は必ずスペースが必要。演算の優先順位的に誤った解釈が発生しうるから。
    - 言語仕様としてメソッド名に`?`を与えられるので、`A?`はメソッド名に、また `X:`はハッシュ中のシンボルを使ったキーにRubyが解釈してしまう。
- 多方向分岐では、`switch`ではなく、Bashとおなじ`case`を使う。
    - `if` も `case` も、ブロックを閉じるのは、`fi` や `esac` ではなく、全て `end`。
    - なので、`end`ばかり並んで可読性が悪くなるようなネストにならないよう、注意。
- 繰り返し制御文として、`for`, `while`, `until` がある。
    - `for`はまず利用しないだろう。`Enumerable` なオブジェクトであれば、メソッドで繰り返し処理（`each`など）が豊富に用意されているから。
- `"Format String" % values"` で、`sprintf("Format String",values)`の[シンタックスシュガーになる](http://docs.ruby-lang.org/ja/2.0.0/method/String/i/=25.html)。
    - なので、Rubyistは`sprintf`は使わないそうな。
- 変数展開可能な文字列中で、`#{}`でくくって、式を囲める。


### 変数・定数

- 宣言されたクラスやモジュールなどは、すべて定数として管理されている。
- 定数は大文字で始まる。全て大文字である必要は、ない。
- グローバル変数は頭に`$`をつける。
    - `$_` のように、Perl と同じような[組み込みの特殊変数](http://docs.ruby-lang.org/ja/2.0.0/class/Kernel.html)もある。
- インスタンス変数には頭に`@`をつける。クラス変数には頭に`@@`をつける。
- `::`は、定数参照時の演算子。`Hoge::Fuga::Piyopiyo`のように使う。なお、`::Hogehoge` でトップレベルの定数を指す。


### 計算、演算

- `++`、`--`演算子はない。
- 演算子は、その実、メソッドである。（`=`以外の演算子はメソッドのようだ）
- 何も考えずに`1/2`、`10/3` と演算しても、結果はそれぞれ`0`、`3`になる。Integerオブジェクトの`/`メソッドがそうしているから。結果をFloatにする場合は、除数か被除数をFloatにする。
- `..` と `...` で[範囲演算子](http://docs.ruby-lang.org/ja/2.0.0/doc/spec=2foperator.html#range)。フリップフロップも使える。
- Perl 同様、`and`, `or`, `not`といった、優先度の低い論理演算子が用意されている。


### 配列、ハッシュ

- [配列](http://docs.ruby-lang.org/ja/1.8.7/class/Array.html)、[ハッシュ](http://docs.ruby-lang.org/ja/1.8.7/class/Hash.html)は、それぞれ`Array.new()`で`Hash.new()`で新しい空の要素を作れるが、次のような記法で、最初から値が入ったものを作れる。

```rb
# 配列の初期化
a0 = []                                         # 空の配列
a1 = ["zero","uno","dos","tres"]

# ハッシュの初期化
h0 = {}                                         # 空のハッシュ
h1 = {"alpha"=>1, "bravo"=>2 }                  # key が文字列
h2 = { :first => "alpha", :second => "bravo" }  # key にシンボルを使用する方法1
h3 = { third: "nagashima", forth: "delta"    }  # key にシンボルを使用する方法2
```

#### 配列

- 配列の参照は、`[]`を使う。
    - `[]`も、[メソッドである](http://docs.ruby-lang.org/ja/2.0.0/class/Array.html#I_--5B--5D)。
- `*`は、配列の内容を展開する。

```shell-session
irb(main):001:0> d=[1,2,3,4]
=> [1, 2, 3, 4]
irb(main):002:0> p d
[1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):003:0> p *d
1
2
3
4
=> [1, 2, 3, 4]
```

- また、`*`をメソッド側の仮引数につけると、この場合は配列化をする（可変長引数などを使う場合に便利）。

```shell-session
irb(main):001:0> def fuga(a, *b)
irb(main):002:1> p a; p b
irb(main):003:1> end
=> nil
irb(main):004:0> fuga(1,2,3,4)
1
[2, 3, 4]
=> [2, 3, 4]
irb(main):005:0> 
```

#### ハッシュ

- ハッシュは、上記のように初期化の際には`{}`を使ったりするが、参照時には配列と同じ`[]`を使う。
    - 配列同様`[]`は[メソッド](http://docs.ruby-lang.org/ja/2.0.0/class/Hash.html#I_--5B--5D)。
- また、ハッシュは、[デフォルト値を設定できる](http://docs.ruby-lang.org/ja/2.0.0/class/Hash.html#S_NEW)。


### クラス/モジュール/メソッド/ブロック

#### クラス

- クラスの継承は単一継承で、複数クラスからの多重継承はできない（モジュールで対応）。
- [クラス](http://docs.ruby-lang.org/ja/2.0.0/doc/spec=2fdef.html#class)やモジュールはネストできる。
    - ネストは、名前空間を共有する以外の意味はなく、継承などが生まれるわけではない。
    - クラスとモジュールで、名前空間を共有できる。
- クラス名は定数として管理されるため、大文字で始まらないと処理系に怒られる。また、[キャメライズせよ](http://qiita.com/takahashim/items/ccfd489c9b26f15b7193)。
- クラスにエイリアス（[alias](http://docs.ruby-lang.org/ja/2.0.0/doc/spec=2fdef.html#alias)）が設定できる。
- クラス定義直下のスコープで実行文を置ける。またそれらは逐次的に実行される。
    - クラス定数などを置いたり、`attr_accessor`（[アクセサを定義する](http://docs.ruby-lang.org/ja/2.0.0/class/Module.html#I_ATTR_ACCESSOR)）など、ユーティリティなメソッド呼び出し文を置いたりする。
- `Klass#initialize`メソッドが初期化関数で、`Klass.new`メソッドがコールされるとこの関数が呼び出される。
    - `Klass`に関しては後述「その他」を参照。
- メソッド内で`super`を呼び出して、スーパークラス（親クラス）のメソッドを呼び出せる。*親クラスそのものではなくてメソッドのコード*なので注意。
- `private` より後ろのメソッド定義は、Privateメソッドになる。

#### モジュール

- モジュールは、インスタンス化できない、機能（部品）を提供としたクラス、といったところ。
- モジュール名も大文字で始まらないと怒られる。同様に[キャメライズ](http://qiita.com/takahashim/items/ccfd489c9b26f15b7193)せよ。
- クラスは、複数のモジュールを取り込むことができる。（Mix-in）
- ざっと言えば、class内で　`include`でインスタンスメソッドとして、`extend`でクラスメソッドとして、任意のモジュールのメソッドを取り込める（[参考](http://pgnote.net/?p=107)）。
- モジュール内でクラスを定義している例があるが、モジュールで名前空間作っているということ。

```rb
module Hoge::Fuga
  class Piyopiyo                # Hoge::Fuga::Piyopiyo
```

#### メソッド

- メソッド呼び出し時に、引数を`()`で括らなくてもよい。
    - ただし、引数の渡し方によっては、`()`で括らないとうまく解釈されない場合があるので、場合に応じてくくる。
- メソッドの最後の演算結果（評価）がメソッドの返り値となる。
    - `return` で明示的に返すことも可能。
- メソッド名の末尾に`!`をつけたものは、破壊的なもの、取り扱いに注意が必要なメソッド、という慣用がある。
    - 配列の中身そのものを置き換える、とか、[エラーを発生させる](http://d.hatena.ne.jp/masterpiyo/20111212/1323677704)とか。
- メソッド名の末尾に`?`をつけたものは、Boolean値を返すもの、という慣用がある。
- 引数にデフォルト値を指定できる。
- [ブロックを渡す場合](http://docs.ruby-lang.org/ja/1.9.3/doc/spec=2fcall.html#yield)は、呼び出し部分の直後に`{}`か`do ~ end`で定義することで渡すことが可能。
    - このブロック部分は、メソッド側から、`yield`によって呼ぶことができる。

```rb
def product(a,b)
  yield a*b
end

product(3,4) do |r|
  p "Result %d" % r
end  
```

- ブロック内ローカル変数のシャドウイング（ブロック外側の同名の変数はブロック側から見えないこと）はない。
 - ブロックのブロックパラメータ宣言部で、`;`のあとに続けて、[シャドウイング対象の変数を指定できる](http://rubytips86.hatenablog.com/entry/2014/03/31/130922)。
- `{}`も`do ~ end`も、どちらもブロックコードとなるが、構文解釈の優先順位が{}と比べて変わるので注意。`do ~ end`は結合度が弱く、[処理系の解釈が意図しない結果となる場合がある](http://qiita.com/riocampos/items/43e4431ddff93e01a18d)。
 
### 正規表現

- m修飾子が、[Perl と違う](http://seuzo.net/entry/2013/06/04/150641)。

### その他

- PerlのPod同様、[Rdocがある](http://qiita.com/kmats@github/items/0c8919a65afbe18e9e37)。
- 幾つかコーディング規約が散見できる（ex. [Cookpad](https://github.com/cookpad/styleguide/blob/master/ruby.ja.md), GitHub [有志翻訳版](http://qiita.com/edwardkenfox/items/33bfadd5fe7c10b9acc5)、とか）が、ざっくり言えば *タブは半角空白2文字* がマスト。
    - あとは、[命名規則](http://qiita.com/takahashim/items/ccfd489c9b26f15b7193)なども参考に。
- ドキュメントやコードのの慣用表現がいくつかある。
 - 式の結果を表すコメント部分は、`# => xxx` のように表す。
 - サンプルコードや実際のコードで、クラスそのものを表すのに、`class`だと読み手が混乱してしまったり、そもそも[予約語で使えなかったり](http://shirusu-ni-tarazu.hatenablog.jp/entry/2014/05/08/001504)するので、`Klass`,`klass`という表記が使われる。（他には、`aliaz`とか）
 - あるメソッドが呼ばれる時、そのメソッドのオブジェクトそのものをさして *レシーバー*（reciever）と称す。
 - クラスメソッドは Klass.method で表す。一方、インスタンスメソッドは Klass#method で表す。コード上はどちらも`reciever.method`で呼び出す。


（おわり）
----