Edited at

「Rubyによるデザインパターン」の要点と使いどころ(続き)

More than 3 years have passed since last update.

「Rubyによるデザインパターン」の要点と使いどころの続きです。

Rubyによるデザインパターン』の「第Ⅲ部 Rubyのためのパターン」についてまとめます。第Ⅲ部は、どの章もそれだけで本が1冊書けるような濃い内容なので、本書を足がかりに別の本も合わせて読んだほうが良さそうです。


DSL: ドメイン特化言語


概要


  • DSL: ドメイン特化言語(Domain-Specific Language)とは、あるドメイン(領域)の言葉を用いてプログラミングができる言語。例えば、会計士が会計の事柄をそのまま表現できる言語など。

  • 外部DSL: 会計士の言葉でプログラミングができる会計用DSLがある場合、そのDSLを解析・実行するためにパーサとインタープリタが必要になる。このように、DSLとインタープリタが別々の場合を外部DSLという。

  • 内部DSL: DSLが何らかの言語(例えばRuby)と同じ書き方ができる場合。Rubyはこの内部DSLを簡単に作ることができる。


実装

内部DSLの実装は、DSLで書かれたファイルをevalメソッドで読み込み、Rubyのプログラムとして実行させている。DSLで使用できるキーワード(メソッド等)は、全て本来プログラム側に定義する。

実行ファイル

def output(message)

puts message
end

eval(File.read('DSLで書かれたファイル'))

DSLで書かれたファイル

output 'メッセージ'

実行結果

メッセージ


メタプログラミング


概要


  • Rubyの柔軟性を活用して、動的なオブジェクトを生成する。


実装

実装例1.インスタンスにメソッドを定義する

def make_object(type)

object = Object.new
if type == :a
def object.type
'a'
end
end
object
end

obj = make_object(:a)
obj.type # => "a"

実装例2.インスタンスにメソッドをextendする

module M

def type
'a'
end
end

def make_object(type)
object = Object.new
if type == :a
object.extend(M)
end
object
end

obj = make_object(:a)
obj.type # => "a"

実装例3.インスタンスにメソッドをclass_eval()で追加する

class Obj

def self.set_type(member)
code = %Q{
def type
"
#{member}"
end
}

class_eval(code)
end
end

Obj.set_type('a')
obj = Obj.new
obj.type # => "a"


Convention over Configuration


概要


  • "設定よりも規約"というRuby on Railsの思想。

  • 従来の"設定"によるフレームワークでは、規模が大きくなるほど設定が大きくなり、拡張性や保守性に問題があった。CoCの思想では、フレームワークがある規約に則ることで、余分な設定を排除し、拡張性や保守性を高めている。