RGBカラー変換プログラムの作成 Ruby

 

今回は、RGB変換プログラムを作成していきます。

テストコードも同時に作成していきます。

📁ruby/

 📁 lib/

  🗂rgb.rb

 📁 test/

  🗂rgb_test.rb

 

RGBカラーとは、1つの色を表すためにRedGreenBlue

R=90、G=35、B=100のように10進数の整数で表現することもあれば、"#5a2364"のように2桁の16進数を3つ並べた文字列で表現されることもあります。

 

[RGB変換プログラムの仕様]

  •  10進数を16進数に変換するto_hexメソッドと、16進数を10進数に変換するto_intsメソッドの2つを定義する。
  • to_hexメソッドは3つの整数を受け取り、それぞれを16進数に変換した文字列を返す。文字列の先頭には"#"を付ける。
  • to_intsメソッドはRGBカラーを表す16進数を受け取り、R、G、Bのそれぞれを10進数の整数に変換した値を配列として返す。

 

to_hexメソッドとto_intsメソッドの実行例

f:id:hide_engineer:20200123101433p:plain

to_hexメソッドとto_intsメソッドの実行例

 

[to_hexメソッドを作成]

 

  • rgb_test.rbに次のようなコードを書きます。

f:id:hide_engineer:20200123103312p:plain

rgb_test.rb

 

  • rgb.rbに次のようなコードを書きます。

    f:id:hide_engineer:20200123104012p:plain

    rgb.rb
  • テストを実行し、ちゃんとパスするか確認します。

これでto_hexメソッドは完成・・・と言いたいところですが、rgb.rbのコードを見てみると、to_s(16).rjust(2, '0')が3回使われていますね。

と言うことで、リファクタリングしましょう!

r、g、bの各値を配列に入れて繰り返し処理する形に直してみます。

f:id:hide_engineer:20200123105603p:plain

rgb.rb (リファクタリング後)

上のコードでは、[r, g, b]というように引数として渡された各値を配列に入れたあと、eachメソッドを使って繰り返し処理しています。eachメソッドの内部では数値を16進数に変換した文字列を、ブロックの外で作成したhex変数に連結しています。そして最後に変数hexをメソッドの戻り値として返却しています。

 

これで、リファクタリング終わり!・・・ではありません。

 

injectメソッドを使うとさらに短くできます。

f:id:hide_engineer:20200123111054p:plain

rgb.rb (injectメソッド、リファクタリング後)

[押さえておきたいポイント]

  • 最初の繰り返し処理ではhexに"#"が入ること
  • ブロックの中のhex + n.to_s(16).rjust(2, '0')で作成された文字は、次の繰り返し処理のhexに入ること
  • 繰り返し処理が最後まで到達したら、ブロックの戻り値がinjectメソッド自身の戻り値になること

というわけで、to_hexメソッドの完成です!

 

[to_intsメソッドを作成]

 

to_intsメソッドの実装で必要な手順は大きく分けて次の2つです。

  • 文字列から16進数の文字列を2文字ずつ取り出す
  • 2桁の16進数を10進数の整列に変換する

 

f:id:hide_engineer:20200123113748p:plain

rgb.rb (to_intsメソッド)

上のコードの処理フローは次の通り

  • 引数の文字列から3つの16進数を抜き出す
  • 3つの16進数を配列に入れ、ループを回しながら10進数の整数に変換した値を別の配列に詰め込む
  • 10進数の整列が入った配列を返す

 

f:id:hide_engineer:20200123114746p:plain

rgb_test.rb

テストは問題なくパスしたと思います。

 

to_hexメソッド同様にリファクタリングしていきましょう。

 

「空の配列を用意して、ほかの配列をループ処理した結果を空の配列に詰め込んでいくような処理の大半はmapメソッドに置き換えることができるはず」

 

to_intsメソッドを見直してみると、mapメソッドに置き換えられそうですね。

 

mapメソッドに置き換えたコードは、次のようになります。

 

f:id:hide_engineer:20200124155524p:plain

rgb.rb (to_intsメソッド リファクタリング後)

 

mapメソッドはブロックの戻り値を配列の要素にして新しい配列を返すメソッドです。

 

なので、わざわざintsのような変数を用意しなくてもmapメソッドとブロックだけで処理が完結します。

 

以上で、to_hexメソッド・to_intsメソッドは完成です!

 

最後まで読んで頂きありがとうございます。

 

[おまけ]

 to_intsメソッドは、正規表現とscanメソッドを使うと

f:id:hide_engineer:20200124160648p:plain

rgb.rb (to_intsメソッド)

たった、1行で実装できるようです!