Rubyやってます、(`・ω・´)ｷﾘｯ という為に押さえときたいテクニック

最近、スタートアップ系や新規開発でRuby(Ruby on Rails)を採用するところも増えてきており、Rubyやってる人がちらほら増えてきた感があるのですが、たま〜にRubyやってて何故それ知らないんだという事もたまにあり、Rubyやってます(`・ω・´)ｷﾘｯ とそれでよく言えるなと呆れる事もありました。。。

そこで、少なくともこれは押さえておいて欲しいテクニックを紹介したいと思います。

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

これはテクニックではないですが、Rubyで最初に躓いたり、混乱する元の一つなので、Rubyをやっている以上、ちゃんと理解しておくべきことであると思ってます

\* 定義したClassから見た表

|名称       |説明              |
|----------|------------------|
|インスタンスメソッド |クラス内で定義されたメソッドのこと|
|インスタンス変数 |インスタンス内で参照可能な変数 |
|クラスメソッド |クラスに対して呼び出すことの出来るメソッド(インスタンス生成せずにアクセス可能) |


```ruby
class Sample

  # クラスメソッド
  def self.hoge    
  end

  def initialize
    @foo = "foo" # インスタンス変数
  end

  # インスタンスメソッド
  def foo
    @foo 
  end

end
```

## Enumerable ★★★★★

[公式doc](https://docs.ruby-lang.org/ja/latest/class/Enumerable.html)

多分C#をやっている人以外は、まずなんて読むのか、から始まると思います。
"エニュメラブル"と読むらしいですが、これはRubyの繰り返し(each)を行うオブジェクトに対して使用する事ができます。これらは組み込みオブジェクトなので、普通にeach内でゴニョゴニョやるよりは、パフォーマンスがいいので、知っておいて損はないです。

### 使い分け

1. もとの配列の各要素を変換して、変換後の新しい配列を作成する -> `map(collect)`
2. 要素が特定の条件を満たしているか -> `all?`, `none?`, `any?`, `one?`
3. 正規表現にマッチする要素を取得する -> `grep`
4. 要素に対して演算した結果を取得する -> `reduce(inject)`
5. 要素のグルーピング -> `group_by`
6. 要素の最小値や最大種を取得する -> `max`, `min`, `minmax`
7. 要素をソートした結果を取得する -> `sort`, `sort_by`
8. 要素を特定の条件で検索した結果を取得する -> `find`, `select`, `find_all`

もちろんHashに対しても`each`が使えるオブジェクトに使用可能です。以前Blogで投稿した内容のほうがイメージし易いので、貼っておきます

[rubyでEnumerableを用いたSQLライクな操作 - のんびりSEの議事録](http://carefree-se.hatenablog.com/entry/2016/05/16/003135)

## Proc/lambda ★★★☆☆

### Proc

ブロックを引数として渡す場合に利用する

```ruby
@num = 0
counter = Proc.new { @num += 1 }
counter.call # 1
counter.call # 2
```

#### ブロックをProcオブジェクトとして受け取る

```ruby
# &blockを引数として渡すと、メソッド内部でProcオブジェクトを呼び出すことが出来る
def agree(&block)
  printf "Hello,"
  block.call if block_given?
end

# yieldを使うことで、上記を省略した書き方ができる
def agree2
  printf "Hey!,"
  yield if block_given? # blockが与えられたかを判定するので、必ず入れておいたほうがいい
end

agree { p "Tom" }
agree2 { p "Sam" }

# Hello,"Tom"
# Hey!,"Sam"
```

ActiveRecordの[transaction](https://github.com/rails/rails/blob/35f32036b6782f8d7960c9636ee4b551dcd29f69/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L225)等、いい例だと思います。

### lambda

lambdaもProcオブジェクトを作成する事ができます。
Proc.newとの違いとして、`return`と`break`の挙動の違い、引数の厳密さが違います。

|メソッド    |return     |break      |
|---------|-----------|-----------|
|Proc.new, Kernel.#proc|メソッドを抜ける|例外が発生する|
|Kernel.lambda|制御を抜ける|制御を抜ける|

```ruby
Proc.new { |x, y| }.call(1) # 1
lambda { |x, y| }.call(1) # ArgumentError
```

また、lambdaは引数を厳密にチェックするので、Rubyで関数型プログラミングっぽいことをするのには、個人的には向いてると思います。

以下がよくまとめられています。

- [Rubyの ブロック、Proc.new、lambdaの違い](http://qiita.com/ryo-ma/items/24c46592b45775e8644d)
- [ブロックやProcの使いどころを理解する](http://qiita.com/kidach1/items/15cfee9ec66804c3afd2)

## nilガード ★★★★☆

`||`(or演算子)を利用したテクニックで、左辺が`nil`, `false` または未定義の場合、右辺にデフォルト値をリテラル指定しておくことで、引数の初期化等に役立ちます。

```ruby
def calc(num)
  num ||= 0
  num += 1
end
```

## 1行if文(if修飾子) ★★★★☆

Rubyでは1行でif文を記述する事ができます。
使い時としては、引数のチェックで`return`や`raise`をする時等、役割を明確にしておくことで、後から見たときにスッキリとしたコードになるのではと思います。

```ruby
def hoge(name)
  return "No name" if name.nil?
  @name = name
end
```

## オブジェクトが持っているmethodを調べる ★★★☆☆

`_methods`メソッドは所有しているメソッドを配列で返してくれるので、既存アプリケーションのコードを調べる際に役立ちます。返して来た結果に対して`select`や`find`等で、効率的にコードを調べることが出来ると思います。

- methods : オブジェクトに対して所有しているメソッドを全て返す
- private_methods : privateメソッド一覧を返す
- protected_methods : protectedメソッド一覧を返す
- public_methods : publicメソッド一覧を返す

## tap ★★☆☆☆

tapメソッドはselfを引数としてブロックを評価し、selfを返します。
メソッドチェーンの途中経過のデバッグにも使えます。
自分はメソッドチェーンを作成するときに利用することも有ります。

- 一般的なメソッドチェーンの例

```ruby
# coding: utf-8

class Calc

  attr_reader :num

  def initialize(num)
    @num = num
  end

  def plus
    @num += 1
    self
  end

  def minus
    @num -= 1
    self
  end

end

calc = Calc.new(1)
calc.plus.plus.plus.minus.plus.minus
p calc.num # 3
```

- tapを利用した場合

selfを返す特性を利用して、メソッドチェーン実装を行ってます

```ruby
# coding: utf-8

class Calc

  attr_reader :num

  def initialize(num)
    @num = num
  end

  def plus
    self.tap { @num += 1 }
  end

  def minus
    self.tap { @num -= 1 }
  end

end

calc = Calc.new(1)
calc.plus.plus.plus.minus.plus.minus
p calc.num
```

[TapがRubyの新たな制御構造の世界を開く](http://melborne.github.io/2012/10/29/rubys-new-control-structure-by-tap-and-break/)

## send ★★☆☆☆

sendメソッドは、レシーバが持っているメソッドを動的に呼び出すことが出来ます。
privateメソッドでさえ呼び出すことが出来るので、用法用量を守り、正しくお使いください。

例えばRSpecで、privateメソッド単体をテストする場合や、渡す引数の数が同じで細部の役割が違うメソッドを動的に呼び出すレシーバを作成するといったことが出来ます。

- 例) Restfulなメソッドを持つクラスのレシーバ

```ruby
class HttpRest

  def get(url, params, opts)
  end

  def post(url, params, opts)
  end

  def put(url, params, opts)
  end

  def delete(url, params, opts)
  end

end

class Client

  attr_reader :response

  def initialize(action, url, params, opts)
    @response = HttpRest.new.send(action.to_sym, url, params, opts)
  end

end
```

## _eval ★★★☆☆

`eval`は基本的に文字列を評価してコードを実行するメソッドですが、rubyには幾つか用途に合わせた`_eval`メソッドが存在します。

- instance_eval : Object内でコードを実行
- class_eval : クラスの中でコードを実行
- module_eval : モジュールの中でコードを実行

これらは、メタプログラミングを行う場合、最低限押さえておきたいメソッドになるかと思います。

[class_evalを利用した動的にmethodを追加する例](https://gist.github.com/kitaro-tn/3692b1f0edffafa5d8351659575f2d97)

## 余談
主にRubyで作られているOSSではよく、DSLを用いる事が多いのですが、最近ではドキュメントを見るより先に、DSLモジュールを探して見たほうが、やってる事が分かるので、調べるのに早いと言うことに気づきました。


## 補足

- grep

> ご指摘いただいた通り、`===`で比較した真となる要素の配列を返すので、正規表現以外でもつかえます

- インスタンスメソッド

> ご指摘いただいたとおり、あるクラスから見た場合は、インスタンスメソッドということになります。
https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html#class_method