銀行員からのRailsエンジニア

銀行員からのRailsエンジニア

銀行員から転身したサービス作りが大好きなRailsエンジニアのブログです。個人で開発したサービスをいくつか運営しており、今も新しいサービスを開発しています。転職して日々感じていること、個人開発サービス運営のことなどを等身大で書いていきます。

【Rubyによるデザインパターンまとめ13】インタプリタパターン

コードの品質向上のため、Rubyデザインパターンを解説した名著である Rubyによるデザインパターン で紹介されているデザインパターンを1つずつまとめており、今回が第13弾です。(毎週1つが目標です!)

前回の記事(ビルダパターンのまとめ)はこちらです。
【Rubyによるデザインパターンまとめ11】ファクトリメソッドパターン - 銀行員からのRailsエンジニア【Rubyによるデザインパターンまとめ12】ビルダパターン - 銀行員からのRailsエンジニア

言葉での説明よりもコードを見た方が分かりやすいので、サンプルコードでの説明をメインにしています。

今回は インタプリタInterpreter)パターン についてまとめました。

f:id:ysk_pro:20200229160054p:plain

インタプリタパターンとは

クラスで表現した文法規則で構文を解析し、その結果得られた手順に基づいて処理を実行するパターンです。

Interpreter」は「通訳」という意味です。

文章の説明よりも実際のコードを見た方が分かりやすので、以下のサンプルコードをご覧ください。

サンプルコード

文字列をプラスマイナスできるプログラムを考えます。

class Word
  def initialize(value)
    @value = value
  end

  def execute
    @value
  end
end

class Plus
  def initialize(first, second)
    @first = first
    @second = second
  end

  def execute
    @first.execute + @second.execute
  end
end

class Minus
  def initialize(first, second)
    @first = first
    @second = second
  end

  def execute
    index = @first.execute =~ /#{@second.execute}/
    second_index = index + @second.execute.length
    @first.execute[0,index] + @first.execute[second_index..-1]
  end
end

class Interpreter
  def self.parse(input)
    @waiting_second_word = false
    words = []
    operations = []
    input.split.each do |value|
      if value =~ /^[^+-].*/ && !@waiting_second_word
        words << Word.new(value)
      else
        if symbol = operations.pop()
          first = words.pop
          second = Word.new(value)
          case symbol
          when /\A\+/
            words << Word.new(Plus.new(first, second).execute)
          when /\A\-/
            words << Word.new(Minus.new(first, second).execute)
          end
          @waiting_second_word = false
        else
          @waiting_second_word = true
          operations << value
        end
      end
    end
    words.pop.execute
  end
end

次のように実行すると

puts Interpreter.parse("おはよう + ございます - ござい")

このような結果になります。

おはようます

サンプルコードはこちらを参考にさせていただきました。
GitHub - piscolomo/ruby-patterns: Examples of Patterns in Ruby

おわりに

ここまで読んでいただきありがとうございます。

Rubyによるデザインパターン の中でも、ファイル検索のプログラムを作る過程を通じて説明されており分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

Rubyによるデザインパターン

Rubyによるデザインパターン

次回は、DSLドメイン特化言語)をまとめます。

来週も頑張ります!

(追記)
DSLドメイン特化言語)についてまとめました!
是非合わせてご覧ください。
ysk-pro.hatenablog.com