Ruby メモ

# メモ Ruby
* 次にふれる機会のための備忘録的に。。

### 規約

- キャメルケース
    - クラス名、モジュール名
- スネークケース(全部小文字)
    - メソッド名、変数名
- 全部大文字のスネークケース
    - 定数
- `;` は1行内に複数文書く場合には文の区切りに使用できるが、めったに使わない。
- メソッド名末尾の！
    - `!` はメソッド名の一部。オブジェクトの内容を変更するメソッド名には `!` を付ける
- メソッド名末尾の？
    - `?` はメソッド名の一部。真偽値を戻す場合はメソッド末尾に `?` を付ける

### 変数

- `_` または小文字アルファベット が先頭
    - ローカル変数
- `$` が先頭
    - グローバル変数
- `@@` が先頭
    - クラス変数
        - クラス変数はクラス定義の中で定義され、クラスの特異メソッドやインスタンスメソッドから参照・代入できる
        - クラス変数の値はクラスのすべてのインスタンスで共有する
            - mutex 的用途に使用する？
- `@` が先頭
    - インスタンス変数
        - インスタンス毎に独立した変数

### コメント

```ruby
#1行コメント

=begin
 複数行コメント
=end

__END__
これ以降は全てコメントとなる
```

### 範囲演算子

- `..` または `...`

```ruby
1..5            # 1 以上 5 以下
1...5           # 1 以上 5 未満
```

### 「===」

- 「==」より緩い比較
- 左辺によって挙動が変わる
    - 数値や文字列の場合は「==」と同じ
    - 正規表現の時はマッチするか
    - クラスの場合はインスタンスか

```ruby
(1..10) === 5             # true
('a'..'f') === "z"        # false

String === "hello"        # true
String === 1              # false

/[0-9]{3}/ === "hello123" # true
/[0-9]{3}/ === "hello"    # false
```

### クラス

- クラスメソッド末尾の =
    - `=` はクラスメソッド名の一部。メンバ変数へのセッターメソッドを意味する
        - 主に `@@` クラス変数のセッターに用いる。
            - `@` インスタンス変数へのセッターは↓の attr_writer か attr_accessor を用いるのが推奨
- attr_read , attr_write, attr_accessor インスタンス変数へのアクセス権限の設定
    
    ```ruby
    class Sample
    	@name = "default"
    	attr_accessor :name
    end 
    ```
    
    - attr_read : read可
    - attr_write : write 可
    - attr_accessor : read と write 可

- 既存クラスにメソッドを直接追加することが可能
    - 既存クラスの変更が可能
- クラスは継承が可能
- alias
    - メソッド名の変更
        - 継承したクラスで、親クラスのメソッドを別名で残す用途に用いる
            - （↑以外で、親クラスのメソッドは呼べない？）
- undef
    - 定義されたメソッドをなかった事にする
        - 継承したクラスで、親クラスのメソッドを使用しないようにする

### シンボル

```ruby
# 例
:name
```

- 用途
    - ハッシュのキー { :key => "value" }
        - {key: "value"} と記載も出来る。この場合の `kye:` はシンボル

### ブロック

```ruby
オプジェクト.メソッド名(引数リスト) do |ブロック変数|
	# 繰り返したい処理
end

オブジェクト.メソッド名(引数リスト) { |ブロック変数|
	# 繰り返したい処理
}
```

- do ... end
    - 繰り返したい処理が複数行に跨る場合によく使用される
    - 引数リストを囲む ( ) は省略可能
- { }
    - 繰り返したい処理が 1行に収まる場合によく使用される
    - 引数がある場合には引数リストを囲む ( ) は省略不可＝引数がない時のみ省略可
        
        

### map, map!

- 配列の要素の数だけブロック内の処理を繰り返し、結果として作成された配列を返す
- map は入力値には無影響。map! は入力値を書き変える。

```ruby
オブジェクト.map do |ブロック変数|
		# 実行したい処理
end
```

### &(ブロック引数）

```ruby
"1,2,3".split(",").map(&:to_i)
=> [1, 2, 3]

# ↑ は ↓の同省略形
"1,2,3".split(",").map {|i| i.to_i } 
```

- to_proc メゾットをもつオブジェクトで使用可能

### 配列：行列的利用

```ruby
# 3x3 の行列を作るとき
a = Array.new(3) do
	[0, 0, 0]
end

# NG ! ↓は 同じ 1x3 のベクトルのインスタンス　が３こ並ぶ
a = Array.new(3, [0,0,0])

	#-- こうなってしまう
	a[0][1] = 2
	P a #=> [[0,2,0],[0,2,0],[0,2,0]]

```

### 例外を発生させる

```ruby
raise "エラーメッセージ #{変数名}"
```

### unless

- if の亜種、偽の時に実行する

### 後置 if , 後置 unless

```ruby
raise "入力値エラー: #{arg1}" unless (0<arg1)

raise "残金なし" if no_money?
```

### メソッドからの戻り値

- return で明示しなくても、メゾッド内の最後の値が戻り値となる。
    - メゾッド末尾の `return` は省略する
        - `return` を記述するのは、早期return が主

### lambdas

- 記述方法は2種類 (↓２つは同じ意味)

```ruby
l1 = lambdas { |arg1| puts arg1 }

l2 = ->(arg1) { puts arg1 }
```

- lambdas メゾッドからの脱出
    - return
        - 使用可: 手続きオブジェクトを抜ける
    - next
        - 使用可: 手続きオブジェクトを抜ける
    - break
        - 使用可: 手続きオブジェクトを抜ける
        

# Tips

### 初期化時

```ruby
# arg1 が nil の時は "" 空文字を入れる
string_hoge = arg1 || ""

# nilチェック付きメソッド呼び出し
#  arg2 が 非nilならメソッド実行　arg2 がnil なら nilが戻る、
item = arg2&.first
```

### tap

- `{}` ブロック内の処理結果に関わらずレシーバ自身を返すので、デバッグ等の処理を、メソッドチェーン内に組み込める。主にデバッグ用

```ruby
( 1 .. 5 )
  .tap{|obj| puts obj.class}
  .to_a.tap{|obj| puts obj.class}
#=> [1, 2, 3, 4, 5]
# 出力結果
# Range
# Array
```

# Array

[class Array](https://docs.ruby-lang.org/ja/latest/class/Array.html)

### new(size) {|index| ... } -> Array

- index を用いた配列生成
    
    ```ruby
    # インデックスを値
    Array.new(3){|i| i}
    => [0, 1, 2]
    
    # インデックス付きの文字列
    Array.new(3){|i| "aaa_#{i}"}
    => ["aaa_0", "aaa_1", "aaa_2"]
    
    # インデックスなしでも回せる
    Array.new(3){rand(0..10)}
    => [4, 6, 3]
    
    # 初期値埋め
    Array.new(3){0}
    => [0, 0, 0]
    ```
    

### drop()

- 先頭から引数要素削除
    
    ```ruby
    [0, 1, 2, 3, 4].drop(1)
    => [1, 2, 3, 4]
    ```
    

### %w

- 配列を作る。配列の要素はスペース区切りで指定する
    
    ```ruby
    a = %w{ a b c d e f }
    a
    **=> ["a", "b", "c", "d", "e", "f"]**
    ```
    

### self & other -> Array

- 集合の積演算、両方の配列に含まれる要素から新しい配列を戻す
    
    ```ruby
    [1, 1, 2, 3] & [3, 1, 4] 
    => [1, 3]
    ```
    

### self * times -> Array

- 配列内容を time 回繰り返したものを戻す
    
    ```ruby
    [1, 2, 3] * 3
    => [1, 2, 3, 1, 2, 3, 1, 2, 3]
    ```
    

### self * sep -> String

- sep を区切り文字に 配列を結合して文字列とする
    
    ```ruby
    # カンマ区切り
    [1,2,3] * ","
    => "1,2,3"
    
    # 区切り文字なしての結合
    ["私", "の", "名前"] * ""
    => "私の名前"
    ```
    

### self + other -> Array

- 自身と other の内容を繋げた 新しい配列を戻す
    - a も b も 変化はしない
    
    ```ruby
    a = [1, 2]
    b = [8, 9]
    a + b     
    => [1, 2, 8, 9]
    ```
    

### self - other -> Array

- 自身から other の要素を取り除いた新しい配列を戻す
    - self 中で重複していて、other中に存在していなかった要素は、その重複は保持される
    
    ```ruby
    # 1 は self側のみなので の重複含めて保持される
    [1, 2, 1, 3, 1, 4] - [4, 2]
    => [1, 1, 3, 1]
    
    # other で 1 が指定されてるので、1 は 重複含めて取り除かれる
    [1, 2, 1, 3, 1, 4] - [1, 4]    # => [2, 3]
    ```
    

### self == other -> bool

- 自身と other の各要素をそれぞれ順に == で比較して、全要素が等しければ true を戻す
    
    ```ruby
    [ "a", "c" ]    == [ "a", "c", 7 ]     #=> false
    [ "a", "c", 7 ] == [ "a", "c", 7 ]     #=> true
    [ "a", "c", 7 ] == [ "a", "d", "f" ]   #=> false
    ```
    

### self[range] = val

- 配列内の range で指定する要素に対して、val での 挿入 または 置換、または削除
    - 破壊的変更
    - val も 配列
    
    ```ruby
    # 置換： renge の長さ = val の長さ
    a=[0, 1, 2, 3, 4, 5]
    a[0..1] = ["a","b"]
    a
    => ["a", "b", 2, 3, 4, 5]
    
    # 挿入: range が first > end の場合は、first 位置に val を挿入
    a = [0,1,2,3,4,5]
    a[2..0] = ["a","b","c"]
    a
    => [0, 1, "a", "b", "c", 2, 3, 4, 5]
    
    # 削除 : val が 空配列 , range 範囲の要素を削除し詰る
    a=[0,1,2,3,4,5]
    a[1..2]=[]
    a
    => [0, 3, 4, 5]
    
    ```
    

### self[start, length] = val

- 配列内の start, length で指定する要素に対して、val での 挿入 または 置換、または削除
    - 破壊的変更
    - val も 配列
    

## デバッグ出力方法

- Rails.logger が使用可能
    - 使用例 ↓

```ruby
def format_header_column(column)
    Rails.logger.debug '================================================'
    Rails.logger.debug column 
    Rails.logger.debug column.unpack('U*').inspect
    column.sub(/^[\uEFBBBF\uFEFF\uFFFE]/, '').strip.gsub(/\r\n|\r|\n| /, '_')
end
```