the hitchhiker’s guide to dsl
DESCRIPTION
Ruby勉強会-8TRANSCRIPT
![Page 1: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/1.jpg)
2008-04-26(土) ;北海道情報大学札幌サテライトRuby勉強会@札幌-8
DSLヒッチハイク・ガイド
The Hitchhiker’s Guide To DSL
日本Rubyの会 / Ruby札幌島田浩二
![Page 2: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/2.jpg)
Don’t Panic!パニクるな
![Page 3: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/3.jpg)
ゴール
![Page 4: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/4.jpg)
✓ Rubyを使ってDSLを作成する際の作戦の立て方と表現のポイントを知る
ゴール
![Page 5: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/5.jpg)
どうぞよろしく
お願いします
![Page 6: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/6.jpg)
DSLとは
![Page 7: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/7.jpg)
DSLDomain Specific Language
![Page 8: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/8.jpg)
✓ ドメインに存在する問題の解決に特化してデザインされたプログラミング言語
DSL
![Page 9: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/9.jpg)
✓ ドメインに存在する問題の解決に特化してデザインされたプログラミング言語
DSL
![Page 10: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/10.jpg)
✓ ドメインの専門用語を反映し、簡潔な方法でドメインの専門知識を表現するもの
DSL
![Page 11: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/11.jpg)
✓ ドメインの専門用語を反映し、簡潔な方法でドメインの専門知識を表現するもの
DSLドメインの専門知識DSL
システム
ドメイン専門家
プログラマ
![Page 12: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/12.jpg)
✓ DSLとそれを解釈するためのプログラミング言語との関係によって分類
DSL
![Page 13: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/13.jpg)
二種類
![Page 14: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/14.jpg)
内部DSL
外部DSLと
![Page 15: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/15.jpg)
内部DSL
外部DSLと内部DSL
汎用言語透過的
![Page 16: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/16.jpg)
内部DSL
外部DSLとRails
Ruby透過的
![Page 17: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/17.jpg)
内部DSL
外部DSLと
外部DSLDSLパーサ
汎用言語
解釈
![Page 18: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/18.jpg)
内部DSL
外部DSLと
XMLAnt
Java
解釈
![Page 19: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/19.jpg)
内部DSL
外部DSLと
![Page 20: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/20.jpg)
✓ ドメインの専門用語を反映し、簡潔な方法でドメインの専門知識を表現するもの
DSL
![Page 21: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/21.jpg)
example
![Page 22: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/22.jpg)
builder = Builder::XmlMarkup.new(:target => STDOUT, :indent => 2)builder.person do |b| b.name “shimada” b.phone “12345678” b.address “Sapporo, Japan”end
<person> <name>shimada</name> <phone>12345678</phone> <address>Sapporo, Japan</address></person>
![Page 23: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/23.jpg)
http://noplans.org/product/t-shirt/
![Page 24: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/24.jpg)
つくり方から理解を深める
![Page 25: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/25.jpg)
DSLのつくりかた
![Page 26: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/26.jpg)
お題
![Page 27: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/27.jpg)
アンケート作成を支援するDSL
http://www.flickr.com/photos/koichiwb/2132785126/
![Page 28: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/28.jpg)
アンケート作成DSL
http://www.flickr.com/photos/koichiwb/2132785126/
✓ 質問と選択肢を入力✓ HTMLに出力
![Page 29: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/29.jpg)
DSLじゃない実現
![Page 30: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/30.jpg)
✓ 1つのメインクラス✓ 2つのバリュー・オブジェクト✓ 1つのライブラリ
DSLじゃない実現
![Page 31: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/31.jpg)
DSLじゃない実現
QuestionQuestionQuestionContext
Questionnaire ERB
![Page 32: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/32.jpg)
DSLじゃない実現
QuestionQuestionQuestionContext
Questionnaire ERB
アンケート全体を表すバリューオブジェクト
質問を表すバリューオブジェクト
アンケートを出力するメインクラス
![Page 33: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/33.jpg)
# Non-DSL Samplectx = Context.new("Ruby勉強会-8のアンケート",[])
ctx.questions << Question.new("勉強会への参加は初めてですか?", ["初めて", "常連"])
ctx.questions << Question.new("今回の勉強会はどうでしたか?", ["良かった", "まあまあ", "最低"])
ctx.questions << Question.new("次回も参加したいですか?", ["したい", "内容によって", "二度とくるか"])
Questionnaire.create_html(ctx)
![Page 34: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/34.jpg)
# Non-DSL Samplectx = Context.new("Ruby勉強会-8のアンケート",[])
ctx.questions << Question.new("勉強会への参加は初めてですか?", ["初めて", "常連"])
ctx.questions << Question.new("今回の勉強会はどうでしたか?", ["良かった", "まあまあ", "最低"])
ctx.questions << Question.new("次回も参加したいですか?", ["したい", "内容によって", "二度とくるか"])
Questionnaire.create_html(ctx)
![Page 35: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/35.jpg)
# Non-DSL Samplectx = Context.new("Ruby勉強会-8のアンケート",[])
ctx.questions << Question.new("勉強会への参加は初めてですか?", ["初めて", "常連"])
ctx.questions << Question.new("今回の勉強会はどうでしたか?", ["良かった", "まあまあ", "最低"])
ctx.questions << Question.new("次回も参加したいですか?", ["したい", "内容によって", "二度とくるか"])
Questionnaire.create_html(ctx)
![Page 36: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/36.jpg)
# Non-DSL Samplectx = Context.new("Ruby勉強会-8のアンケート",[])
ctx.questions << Question.new("勉強会への参加は初めてですか?", ["初めて", "常連"])
ctx.questions << Question.new("今回の勉強会はどうでしたか?", ["良かった", "まあまあ", "最低"])
ctx.questions << Question.new("次回も参加したいですか?", ["したい", "内容によって", "二度とくるか"])
Questionnaire.create_html(ctx)
![Page 37: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/37.jpg)
# Non-DSL Samplectx = Context.new("Ruby勉強会-8のアンケート",[])
ctx.questions << Question.new("勉強会への参加は初めてですか?", ["初めて", "常連"])
ctx.questions << Question.new("今回の勉強会はどうでしたか?", ["良かった", "まあまあ", "最低"])
ctx.questions << Question.new("次回も参加したいですか?", ["したい", "内容によって", "二度とくるか"])
Questionnaire.create_html(ctx)
![Page 38: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/38.jpg)
class Question attr_accessor :title, :answers def initialize title, answers @title = title @answers = answers endend
class Context attr_accessor :title, :questions def initialize title, questions @title = title @questions = questions endend
class Questionnaire TEMPLATE = ... def self.create_html(context) puts ERB.new(TEMPLATE).result(binding) endend
![Page 39: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/39.jpg)
class Question attr_accessor :title, :answers def initialize title, answers @title = title @answers = answers endend
class Context attr_accessor :title, :questions def initialize title, questions @title = title @questions = questions endend
class Questionnaire TEMPLATE = ... def self.create_html(context) puts ERB.new(TEMPLATE).result(binding) endend
![Page 40: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/40.jpg)
class Question attr_accessor :title, :answers def initialize title, answers @title = title @answers = answers endend
class Context attr_accessor :title, :questions def initialize title, questions @title = title @questions = questions endend
class Questionnaire TEMPLATE = ... def self.create_html(context) puts ERB.new(TEMPLATE).result(binding) endend
![Page 41: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/41.jpg)
class Question attr_accessor :title, :answers def initialize title, answers @title = title @answers = answers endend
class Context attr_accessor :title, :questions def initialize title, questions @title = title @questions = questions endend
class Questionnaire TEMPLATE = ... def self.create_html(context) puts ERB.new(TEMPLATE).result(binding) endend
![Page 42: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/42.jpg)
class Question attr_accessor :title, :answers def initialize title, answers @title = title @answers = answers endend
class Context attr_accessor :title, :questions def initialize title, questions @title = title @questions = questions endend
class Questionnaire TEMPLATE = ... def self.create_html(context) puts ERB.new(TEMPLATE).result(binding) endend
![Page 43: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/43.jpg)
DSLじゃない実現実際に見てみる
![Page 44: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/44.jpg)
✓ プログラマにとっては普通のやり方✓ アンケートを作る人には使いづらい
DSLじゃない実現
![Page 45: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/45.jpg)
✓ これをベースにアンケートを作る人でも使えるようなDSLに
DSLじゃない実現
![Page 46: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/46.jpg)
DSLによる実現
![Page 47: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/47.jpg)
グローバル・メソッドを使って
作戦その1
![Page 48: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/48.jpg)
グローバル・メソッドを使って
DSLのイメージ
![Page 49: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/49.jpg)
context "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 50: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/50.jpg)
context "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 51: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/51.jpg)
context "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 52: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/52.jpg)
context "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 53: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/53.jpg)
context "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 54: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/54.jpg)
グローバル・メソッドを使って
DSLの実装
![Page 55: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/55.jpg)
def context text @target = Context.new(text, []) yield puts ERB.new(TEMPLATE).result(binding)end
def question text q = Question.new(text, []) yield q @target.questions << qend
![Page 56: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/56.jpg)
def context text @target = Context.new(text, []) yield puts ERB.new(TEMPLATE).result(binding)end
def question text q = Question.new(text, []) yield q @target.questions << qend
![Page 57: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/57.jpg)
def context text @target = Context.new(text, []) yield puts ERB.new(TEMPLATE).result(binding)end
def question text q = Question.new(text, []) yield q @target.questions << qend
![Page 58: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/58.jpg)
def context text @target = Context.new(text, []) yield puts ERB.new(TEMPLATE).result(binding)end
def question text q = Question.new(text, []) yield q @target.questions << qend
![Page 59: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/59.jpg)
グローバル・メソッドを使って
実際に見てみる
![Page 60: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/60.jpg)
context "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 61: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/61.jpg)
表現のポイント✓ 問題領域の語彙をメソッド名に✓ ()の省略✓ ブロックの使用
![Page 62: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/62.jpg)
✓ メソッドが増えると管理が困難✓ 小さい規模のDSL向けの戦略
グローバル・メソッドを使って
![Page 63: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/63.jpg)
大きいDSLを作るには?
![Page 64: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/64.jpg)
その前にちょっと寄道
![Page 65: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/65.jpg)
表現の追求
![Page 66: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/66.jpg)
context "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 67: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/67.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 68: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/68.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
名前付き引数の導入
![Page 69: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/69.jpg)
名前付き引数の導入
DSLの実装
![Page 70: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/70.jpg)
def context text @target = Context.new(text, []) yield puts ERB.new(TEMPLATE).result(binding)end
def question text q = Question.new(text, []) yield q @target.questions << qend
![Page 71: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/71.jpg)
def context args @target = Context.new(args[:title], []) yield case args[:to] when :html puts ERB.new(TEMPLATE).result(binding) else p @target endend
def question text ...end
![Page 72: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/72.jpg)
def context args @target = Context.new(args[:title], []) yield case args[:to] when :html puts ERB.new(TEMPLATE).result(binding) else p @target endend
def question text ...end
引数にキーでアクセス
![Page 73: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/73.jpg)
表現のポイント✓ シンボルとハッシュで名前付き引数の使用✓ 意図をより明確に表現✓ 全てがオブジェクトであることを利用した表現
![Page 74: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/74.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 75: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/75.jpg)
表現の追求(その2)
![Page 76: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/76.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
![Page 77: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/77.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do |q| q.answers << "初めて" q.answers << "常連" end question "今回の勉強会はどうでしたか?" do |q| q.answers << "良かった" q.answers << "まあまあ" q.answers << "最低" end question "次回も参加したいですか?" do |q| q.answers << "したい" q.answers << "内容によっては" q.answers << "二度と来ない" endend
冗長なのでなんとかしたい
![Page 78: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/78.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 79: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/79.jpg)
def context args ...end
def question text q = Question.new(text, []) yield q @target.questions << qend
![Page 80: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/80.jpg)
def context args ...end
def question text @target.questions << Question.new(text, yield)end
![Page 81: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/81.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 82: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/82.jpg)
だいぶアンケートらしく書けるようになった
![Page 83: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/83.jpg)
その前にちょっと寄道ed
![Page 84: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/84.jpg)
大きいDSLを作るには?
![Page 85: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/85.jpg)
オブジェクトを使って
作戦その2
![Page 86: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/86.jpg)
オブジェクトを使って
DSLのイメージ
![Page 87: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/87.jpg)
Questionnaire.context :to => :html, :title => "R..." do |q| q.question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end q.question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end q.question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 88: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/88.jpg)
Questionnaire.context :to => :html, :title => "R..." do |q| q.question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end q.question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end q.question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 89: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/89.jpg)
Questionnaire.context :to => :html, :title => "R..." do |q| q.question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end q.question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end q.question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 90: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/90.jpg)
Questionnaire.context :to => :html, :title => "R..." do |q| q.question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end q.question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end q.question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 91: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/91.jpg)
オブジェクトを使って
DSLの実装
![Page 92: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/92.jpg)
def Questionnaire ... def self.context args q = Question.new(args[:title], []) yield self ... end
def self. question text ... endend
![Page 93: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/93.jpg)
Questionnaire.context :to => :html, :title => "Ruby勉強会-8の..." do |q| q.question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end q.question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end q.question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 94: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/94.jpg)
表現のポイント
✓ クラス・メソッドを利用してDSLを実現✓ メソッドを管理しやすい✓ 若干記述が冗長に
![Page 95: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/95.jpg)
メタプログラミングを使って
作戦その3
![Page 96: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/96.jpg)
DSLのイメージ
メタプログラミングを使って
![Page 97: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/97.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 98: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/98.jpg)
オブジェクトを使って
DSLの実装
![Page 99: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/99.jpg)
def method_missing sym, *args case sym when :context @target = Context.new(args[0][:title], []) yield case args[0][:to] when :html puts ERB.new(TEMPLATE).result(binding) else p @target end when :question q = Question.new(arg[0], yield) @target.questions << q endend
![Page 100: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/100.jpg)
def method_missing sym, *args case sym when :context ... when :question ...
![Page 101: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/101.jpg)
def method_missing sym, *args case sym when :context ... when :question ...
![Page 102: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/102.jpg)
def method_missing sym, *args case sym when :context ... when :question ...
![Page 103: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/103.jpg)
when :context @target = Context.new(args[0][:title], []) yield case args[0][:to] when :html ... end when :question q = Question.new(arg[0], yield) @target.questions << q end
![Page 104: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/104.jpg)
def method_missing sym, *args case sym when :context @target = Context.new(args[0][:title], []) yield case args[0][:to] when :html puts ERB.new(TEMPLATE).result(binding) else p @target end when :question q = Question.new(arg[0], yield) @target.questions << q endend
![Page 105: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/105.jpg)
context :to => :html, :title => "Ruby勉強会-8のアンケート" do question "勉強会への参加は初めてですか?" do [ "初めて", "常連" ] end question "今回の勉強会はどうでしたか?" do [ "良かった", "まあまあ", "最低"] end question "次回も参加したいですか?" do [ "したい", "内容によっては", "二度と来ない"] endend
![Page 106: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/106.jpg)
def method_missing sym, *args case sym when :context @target = Context.new(args[0][:title], []) yield case args[0][:to] when :html puts ERB.new(TEMPLATE).result(binding) else p @target end when :question q = Question.new(arg[0], yield) @target.questions << q endend
![Page 107: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/107.jpg)
表現のポイント✓ メソッドを定義せずに動的に機能を実現✓ 利用者の負担は最低限に✓ 拡張も容易
![Page 108: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/108.jpg)
まとめ
![Page 109: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/109.jpg)
✓ ドメインの専門用語を反映し、簡潔な方法でドメインの専門知識を表現するもの
DSL
![Page 110: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/110.jpg)
作戦の立て方
![Page 111: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/111.jpg)
大きな作戦✓ グローバル・メソッド✓ オブジェクト✓ ex) クラス・メソッドの使用
✓ メタプログラミング✓ ex) method_missingの使用
![Page 112: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/112.jpg)
小さな作戦✓ 問題領域の語彙をメソッド名に✓ 省略記法の使用✓ 名前付き引数による表現✓ ブロックによる表現
![Page 113: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/113.jpg)
表現のポイント
![Page 114: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/114.jpg)
表現のポイント✓ 利用者の負担は最低限に✓ 利用者の語彙で、記述は少なく
✓ 意図をより明確に✓ 何をどこに書けば良いかを明らかに
✓ 内部表現も併せて考える✓ 管理の容易性、スコープ
![Page 115: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/115.jpg)
see also
![Page 116: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/116.jpg)
![Page 117: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/117.jpg)
for a good DSL hitchhiking!より良いヒッチハイクを!
![Page 118: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/118.jpg)
ご清聴ありがとうございました
![Page 119: The Hitchhiker’s Guide To Dsl](https://reader033.vdocument.in/reader033/viewer/2022042814/55500895b4c90579108b5680/html5/thumbnails/119.jpg)
何かご質問は?