コードの品質向上のため、Rubyでデザインパターンを解説した名著である Rubyによるデザインパターン で紹介されているデザインパターンを1つずつまとめており、今回が第13弾です。(毎週1つが目標です!)
前回の記事(ビルダパターンのまとめ)はこちらです。
【Rubyによるデザインパターンまとめ11】ファクトリメソッドパターン - 銀行員からのRailsエンジニア【Rubyによるデザインパターンまとめ12】ビルダパターン - 銀行員からのRailsエンジニア
言葉での説明よりもコードを見た方が分かりやすいので、サンプルコードでの説明をメインにしています。
今回は インタプリタ(Interpreter)パターン についてまとめました。
インタプリタパターンとは
クラスで表現した文法規則で構文を解析し、その結果得られた手順に基づいて処理を実行するパターンです。
「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によるデザインパターン の中でも、ファイル検索のプログラムを作る過程を通じて説明されており分かりやすかったので、ご興味ある方は是非合わせてご覧ください。
- 作者:Russ Olsen,ラス・オルセン
- 発売日: 2009/04/01
- メディア: 単行本
来週も頑張ります!
(追記)
DSL(ドメイン特化言語)についてまとめました!
是非合わせてご覧ください。
ysk-pro.hatenablog.com