Ruby初学者が戸惑いやすい文法を、例を交えて噛み砕いてみる



初めてRubyやRailsに触れる人だと一見してどういう仕組みかわかりにくい記述があったりします。そんな戸惑い易い文法を例を交えて紹介します。

## 環境

```sh
$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin16]
```

```ruby
rails (5.2.0)
```

## 戸惑い易い文法の例

今回はリダイレクトする際のに使う `redirect_to` の記述を例として噛み砕いていきます。

```ruby:Railsでありがちな/photosへのリダイレクト例
redirect_to photos_path, status: :found
```

※この `redirect_to` そのものの説明は[Railsガイド](https://railsguides.jp/layouts_and_rendering.html)で記載されているのでそちらをご参照ください。

この記述を理解するためには

* メソッド呼び出し時の引数括弧の空白化
* 引数無しメソッドの括弧書き省略
* シンボル
* シンボルをキーにしたハッシュの直接記述（ハッシュ式のリテラル）
* 引数にハッシュを使う際の中括弧省略

上記にあげたRubyの文法やしくみを知る必要があるので、順番に例を交えて説明します。


## 文法の説明と例


### メソッド呼び出し時の引数括弧の空白化

Rubyのメソッドを呼び出す時は`(` と `)` の括弧書きを省略して空白を開けることで同等の処理をすることができまる。


#### 例


下記のようなメソッドがあった場合…

```ruby
def sample_method(example_value)
  puts example_value
end
```

以下の2つの記述はどちらとも同じ結果になります。

```
# どちらも同じ結果になる
sample_method("test")
sample_method "test"
```

### 引数無しメソッドの括弧書き省略

Rubyでは引数がないメソッドの場合、括弧書きを省略することができるので、見た目として変数と同じように書き表すことができます。

#### 例


下記のようなメソッドがあった場合…

```ruby
def sample_method2
  puts "It's a test"
end
```

以下の2つの記述はどちらとも同じ結果になります。

```
# どちらも同じ結果になる
sample_method2()
sample_method2
```


### シンボル

シンボルとは `:` と `文字列` の組み合わせで一意の値が表現できるものです。

採用されている言語が少なく、とっつきにくいのですが、Qiitaの記事にわかりやすく記述されている方がいたので引用します。

> 文字列の皮を被った数値。コード上は文字列で見えてるけど内部では数値として扱われる。
>
> [Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい](https://qiita.com/Kta-M/items/53a13ef60e14fcb41193)

今回は `:str` のような記述はシンボルと呼ばれる表記法であるということを理解していだければ問題ありません。

もし詳しい概念を理解されたい場合は引用した記事を読んでいただくとグッと理解が深まると思います。

#### 例

```ruby
a = :test
a == :test
# => true

# 代入したものと比較しても分かる
b = :test
a == b
# => true

# 文字列とは概念が異なる
c = "test"
a == c
# => false
```

### シンボルをキーにしたハッシュの直接記述（ハッシュ式のリテラル）

Rubyではハッシュを以下のように、プログラム内で記述することができます。

```ruby
# hash_varに キーが "key"、値が 1のハッシュを代入する
hash_var = {"key" => 1}
```

ただし、シンボルをキーにしたい場合は
`{シンボル名: 値}` で書き表すこともできます。


#### 例

```ruby
hash = {key_symbol: 1}
# => {:key_symbol=>1}
```

### 引数にハッシュを使う際の中括弧省略

Rubyで引数にハッシュを指定する場合は `{` と `}` の中括弧を省略することができます。

#### 例

下記のようなメソッドを用意し…

```ruby
def arg_hash_sample(arg_hash)
  arg_hash.each do |key, value|
    puts "------"
    p key
    p value
    puts "------"
  end
end
```

以下のように実行すると…

```ruby
arg_hash_sample("key1" => "value","key2" => "value")
```

結果は以下のようになります。

```text:出力結果
------
"key1"
"value"
------
------
"key2"
"value"
------
```

## 文法の意味を踏まえて噛み砕いてみる

改めてリダイレクトの内容を噛み砕いてみる

```ruby:順番に噛み砕いてみる
redirect_to photos_path, status: :found

# メソッド呼び出し時の引数括弧が省略されているのでつけてみる
redirect_to(photos_path, status: :found)

# phots_pathは引数のないメソッドなので括弧をつけてみる
redirect_to(photos_path(), status: :found)

# 第二引数はシンボルも値もキーを指定したハッシュなのでわかりやすいように中括弧をつけてみる
redirect_to(photos_path(), {:status => :found} )
```

ここまで噛み砕くと、他の言語でもありそうな記述になったので、他のプログラミング言語をやったことならピンと来やすい記述になったのではないでしょうか

## あとがき

いろいろ思うところがあってこの記事を書いたので、その経緯はブログに書いてあります。
[Railsで簡潔になったメソッド呼び出しの仕組みを説明するための記事を書いた \- コード日進月歩](http://shinkufencer.hateblo.jp/entry/2018/08/23/233000)

## 参考リンク

* [リテラル \(Ruby 2\.5\.0\)](https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html)
* [ruby引数処理に使えるテクニック](https://qiita.com/metheglin/items/306e81c95f8a5cdea296)
* [Rubyのメソッドの引数受け渡しまとめ](https://qiita.com/raccy/items/1168c7e8849dedf70fa4)
* [Rubyコーディングアンチパターン \- Qiita](https://qiita.com/seiya1121/items/6fcd8a1ab332a4f14439)