[備忘録] [初心者] Rubyの書き方メモ(リファクタリング) 1

## 概要
[前回の投稿](https://qiita.com/RiSE_blackbird/items/b4c597a87daeed9d414c)で掲載していたRubyのコードがRubyらしい書き方になっていないことに気づいたので、修正も兼ねて勉強のメモを残します。

下記記事を拝見したのがきっかけで、勉強のために実際に内容を参考にさせて頂きながら前回投稿分のコードを例にして修正してみました。
**[[初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか | Qiita](https://qiita.com/jnchito/items/dedb3b889ab226933ccf)**

## コード

### 修正前
~~~rb:Upcasing.rb
def Upcasing(result_lines)
  result_lines[0] = result_lines[0].capitalize
  break_flg = false
  ## ④ Rubyでのハッシュの記法 (修正せず:できなかった理由は後述)
  break_sign = { "."=>true, "!"=>true, "?"=>true, ","=>false }

  result_lines.each_index do |i|
    ## ① 条件分岐と真偽値
    if break_flg == true
      result_lines[i] = result_lines[i].capitalize
    end

    ## ② 配列要素の指定方法、文字列中の指定番の文字の参照
    if break_sign[result_lines[i].slice(-1)] == true
      break_flg = true
    else
      break_flg = false
    end
  end
  joined_line = result_lines.join(" ")
  ## ③ Rubyでの戻り値の表記
  return joined_line
end

print Upcasing(["oh,", "yeah!", "hello!"])

## 実行結果
## Oh, yeah! Hello!
~~~

### 変更点
~~~diff
def Upcasing(result_lines)
  result_lines[0] = result_lines[0].capitalize
  break_flg = false
  ## ④ Rubyでのハッシュの記法 (修正せず、変更できなかった理由は後述)
  break_sign = { "."=>true, "!"=>true, "?"=>true, ","=>false }

  result_lines.each_index do |i|
    ## ① 条件分岐と真偽値
-   if break_flg == true
+   if break_flg
      result_lines[i] = result_lines[i].capitalize
    end

    ## ② 配列要素の指定方法、文字列中の指定番の文字の参照
-   if break_sign[result_lines[i].slice(-1)] == true
+   if break_sign[result_lines[i][-1]]   
      break_flg = true
    else
      break_flg = false
    end
  end
  joined_line = result_lines.join(" ")
  ## ③ Rubyでの戻り値の表記
- return joined_line
end

print Upcasing(["oh,", "yeah!", "hello!"])

~~~

### 修正後
~~~rb:Upcasing.rb
def Upcasing(result_lines)
  result_lines[0] = result_lines[0].capitalize
  break_flg = false
  break_sign = { "."=>true, "!"=>true, "?"=>true, ","=>false }

  result_lines.each_index do |i|
    if break_flg
      result_lines[i] = result_lines[i].capitalize
    end
    
    if break_sign[result_lines[i][-1]]
      break_flg = true
    else
      break_flg = false
    end
  end
  joined_line = result_lines.join(" ")
end

print Upcasing(["oh,", "yeah!", "hello!"])

## 実行結果
## Oh, yeah! Hello!
~~~

## 各修正箇所の詳細

検討箇所①〜④について、番号順に追っていきます。

### ① 条件分岐と真偽値

~~~diff
-   if break_flg == true
+   if break_flg
~~~

[制御構造 > if | Ruby 2.7.0 リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/doc/spec=2fcontrol.html#if)

恥ずかしいことですが、惰性で使いすぎていて、式として変数単体を記載するとその真偽を返すという根本的な仕様を理解していませんでした。Rubyに限った話ですらないですね・・・。
少なくとも、Rubyでは単純な真偽判定で(== true)を書かないようにします。

~~~rb:Ruby
hoge = true
p hoge
if hoge; hoge = false; end
p hoge

# true
# false
~~~

~~~js:JavaScript
var hoge = true;
console.log(hoge);
if (hoge) hoge = false;
console.log(hoge);

// true
// false
~~~

~~~cs:C#
public class Hello{
  public static void Main(){
    bool hoge = true;
    System.Console.WriteLine(hoge);
    if (hoge){ hoge = false; }
    System.Console.WriteLine(hoge);
  }
}

// True
// False
~~~

### ② 配列要素の指定方法、文字列中の指定番の文字の参照

~~~diff
-   if break_sign[result_lines[i].slice(-1)] == true
+   if break_sign[result_lines[i][-1]]
~~~

- [Methods > []　(String) | API documentation for Ruby 2.7.1.](https://ruby-doc.org/core-2.7.1/String.html#method-i-5B-5D)  
  文字列の後ろに[]をつけて文字番号を指定できることを初めて知りました。  
  負のインデックスによって後ろから数えられるのは便利ですね。
- [Methods > []　(Array) | API documentation for Ruby 2.7.1.](https://ruby-doc.org/core-2.7.1/Array.html#method-i-5B-5D)  
  配列要素の番号についても同様らしく、負のインデックスが、配列の末尾からの計算を意味することが明記されています。

### ③ Rubyでの戻り値の表記
~~~diff
def Upcasing(result_lines)
  ##
  ## コード省略
  ##
  joined_line = result_lines.join(" ")
- return joined_line
end
~~~

- [クラス／メソッドの定義 > メソッドの評価 | Ruby 2.7.0 リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html#eval_method)  
returnが呼ばれなかった場合は、本体の最後の式の値が返されることになるので、わざわざ修正前のように1行分記載する必要がありません。

## ④ Rubyでのハッシュの記法
~~~rb
break_sign = { "."=>true, "!"=>true, "?"=>true, ","=>false }
~~~
初めは、下記のようにシンボルを用いた記法に修正しようとしました。

~~~rb:修正案
break_sign = { ".": true, "!": true, "?": true, ",": false }
~~~

上記のように変更すると、上位のメソッドのデバッグ結果が変わってしまいました。
そこで、ハッシュの中身を確認すると、以下のように格納されるキー"!"が文字列では無くなっていました。

~~~rb
break_sign = { "."=>true, "!"=>true, "?"=>true, ","=>false }
p break_sign
#=> {"."=>true, "!"=>true, "?"=>true, ","=>false}

break_sign = { ".": true, "!": true, "?": true, ",": false }
p break_sign
#=>{:"."=>true, :!=>true, :"?"=>true, :","=>false}

~~~

- [Hash | API documentation for Ruby 2.7.1.](https://ruby-doc.org/core-2.7.1/Hash.html)  
  記法のバリエーションや各種関連メソッドについての説明はドキュメントで説明されています。


どうにかシンボルを使って表現しようとも考えたのですが、そもそもハッシュのキーに特殊文字一文字を当てる場面がそんなにあるのだろうかと疑問に思い、今回はスルーすることにしました。
この件に関して、また気づきがあれば別途投稿します。