RubyでDSL

8,738 views

Published on

簡単なRubyでのDSL実装のお話

Published in: Technology
0 Comments
17 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
8,738
On SlideShare
0
From Embeds
0
Number of Embeds
112
Actions
Shares
0
Downloads
34
Comments
0
Likes
17
Embeds 0
No embeds

No notes for slide

RubyでDSL

  1. 1. 「安心・安全・安定・信頼」できるインターネットサービスを 株式会社クルウィット 井澤 志充 RubyでDSL Kanazawa.rb #12
  2. 2. 「安心・安全・安定・信頼」できるインターネットサービスを じこしょうかい • (株)クルウィットの取締役  兼  北北陸陸⽀支社⻑⾧長 • 博⼠士(情報科学) 2 • ネットワークの委託研究・⾃自社サービス開発など • 井澤  志充  (いざわゆきみつ)
  3. 3. 「安心・安全・安定・信頼」できるインターネットサービスを DSLってなに? 3
  4. 4. 「安心・安全・安定・信頼」できるインターネットサービスを DSLってなに? 3 Domain Specific Language ドメイン特化言語
  5. 5. 「安心・安全・安定・信頼」できるインターネットサービスを DSLってなに? 3 Domain Specific Language ドメイン特化言語 →特化
  6. 6. 「安心・安全・安定・信頼」できるインターネットサービスを 比較 4 普段皆さんがプログラミングでつかっ ている言語は →汎用プログラミング言語
  7. 7. 「安心・安全・安定・信頼」できるインターネットサービスを 比較 4 普段皆さんがプログラミングでつかっ ている言語は →汎用プログラミング言語 →汎用
  8. 8. 「安心・安全・安定・信頼」できるインターネットサービスを 比較(2) 5 「汎用」 はんよう【汎用】 (名)スル 広くいろいろな方面に用いること。また,そのもの。「―性」 「特化」 とっか 【特化】 (名)スル 他と異なる特別なものとすること。特殊化すること。「精密機器に―した生産ラ イン」
  9. 9. 「安心・安全・安定・信頼」できるインターネットサービスを DSLとは(再) 6 特定の目的を達成するために作られるプ ログラミング言語 例: Makefile SQL yacc, lex Shell Script RSpec
  10. 10. 「安心・安全・安定・信頼」できるインターネットサービスを 汎用言語と比べると • 利点 • 目的を達成するための最低限の実装でよい • ループや制御構造などを実装しないで良いかも • 特定の目的に特化できるので、想定利用者を限定可能 • 専門家が分かる表現で良い • コード自体が問題を完結に記述したものである • 自然言語風に書けるものが多い 7
  11. 11. 「安心・安全・安定・信頼」できるインターネットサービスを 汎用言語と比べると • 欠点 • 特殊な言語であるため、お作法の学習コストの高さ • 特化型ゆえ応用範囲は本来的に狭い 8
  12. 12. 「安心・安全・安定・信頼」できるインターネットサービスを DSLの分類 9 外部DSL • インタプリタあるいはコンパイラを自作するのに近い • 字句解析器・構文解析器を使った言語設計 • 全て自分で決めることが出来る →全て自分でやる必要がある
  13. 13. 「安心・安全・安定・信頼」できるインターネットサービスを DSLの分類 10 内部DSL • 汎用プログラミング言語を利用 • 汎用プログラミング言語の持つ拡張性を利用 • 利用する言語によって自由度が異なる
  14. 14. 「安心・安全・安定・信頼」できるインターネットサービスを Rubyと内部DSL 11 Rubyで作られた内部DSL • RSpec • ActiveRecord • migration • Rubyの言語仕様の範囲で作ることになる • Rubyの予約語はそのまま使える • 記述言語 = Rubyのコード
  15. 15. 「安心・安全・安定・信頼」できるインターネットサービスを 使えそうな要素 12 • Rubyのメソッドは ( ) を省略できる • ブロックは、do - end で記述できる • 強力な eval 機能 • instance_eval
  16. 16. 「安心・安全・安定・信頼」できるインターネットサービスを instance_evalとは 13 http://doc.ruby-lang.org 先生曰く、 instance_eval(expr, filename = "(eval)", lineno = 1) -> object[permalink] instance_eval {|obj| ... } -> object ・オブジェクトのコンテキストで文字列exprまたはオブジェクト自身を ブロックパラメータとするブロックを 評価してその結果を返します。 ・オブジェクトのコンテキストで評価するとは評価中の self をそのオ ブジェクトにして実行するということです。 ・また、文字列 expr やブロック中でメソッドを定義すればそのオブジ ェクトの特異メソッドが定義されます。
  17. 17. 「安心・安全・安定・信頼」できるインターネットサービスを 簡単なコード 14
  18. 18. 「安心・安全・安定・信頼」できるインターネットサービスを 簡単なコード 14 コード cat = 'tama' cat.instance_eval { def hello puts “meow” end } cat.hello 実行結果 #=> “meow”
  19. 19. 「安心・安全・安定・信頼」できるインターネットサービスを 「とりあえず」つくってみようか 15
  20. 20. 「安心・安全・安定・信頼」できるインターネットサービスを 「とりあえず」つくってみようか 15
  21. 21. 「安心・安全・安定・信頼」できるインターネットサービスを お題 • イベントカレンダー記述⾔言語 • ⾔言語仕様 • 予約語: • event • カレンダーイベントの定義開始。引数としてイベントのタイト ルと詳細情報のブロックを持つ • on  …  ⽇日程 • starts  …  開始時刻 • ends  …  終了了時刻 16
  22. 22. 「安心・安全・安定・信頼」できるインターネットサービスを 作成する言語の記述例 17 Beer Paryというイベントが 2013/08/24 の 13:00∼17:00 にあるよ! event “Beer Party” do on “2013/08/24” starts “13:00” ends “17:00” end
  23. 23. 「安心・安全・安定・信頼」できるインターネットサービスを 言語解釈器の作成 18 class CalEvent def initialize(title) @title = title @date = @start_time = @end_time = nil end def on(date) @date = Date.parse(date) end def show print "title:#{@title}, on #{@date}, starts #{@start_time}, ends #{@end_time}n" end end def event(title, &block) cal = CalEvent.new(title) cal.instance_eval(&block) cal.show end load File.expand_path(ARGV[0])
  24. 24. 「安心・安全・安定・信頼」できるインターネットサービスを 実行結果 19 % ruby calendar.rb calendar.txt title:beer party, on 2013-08-24, starts 13:00, ends 17:00
  25. 25. 「安心・安全・安定・信頼」できるインターネットサービスを 言語解釈器の拡張 20 • 追加⾔言語仕様 • 予約語: • every • 繰り返しを表す定義の開始。引数として繰り返しのタイミング を表す⽂文字列列と詳細情報のブロックを持つ
  26. 26. 「安心・安全・安定・信頼」できるインターネットサービスを 21 Beer Paryというイベントが 毎週土曜日 の 13:00∼17:00 にあるよ! event “Beer Party” do every “week” do wday “saturday” end starts “13:00” ends “17:00” end
  27. 27. 「安心・安全・安定・信頼」できるインターネットサービスを 言語解釈器の拡張 22 class CalEvent def initialize(title) @title = title @date = @start_time = @end_time = nil end : class Every def initialize(method) @method = method @wday = nil end : end def every(method, &block) @every = Every.new(method) @every.instance_eval(&block) end : def show @every.generate.each { |date| : } end
  28. 28. 「安心・安全・安定・信頼」できるインターネットサービスを 実行結果 23 % ruby calendar.rb calendar.txt title:beer party, on 2013-08-03, starts 13:00, ends 17:00 title:beer party, on 2013-08-10, starts 13:00, ends 17:00 title:beer party, on 2013-08-17, starts 13:00, ends 17:00 title:beer party, on 2013-08-24, starts 13:00, ends 17:00 title:beer party, on 2013-08-31, starts 13:00, ends 17:00
  29. 29. 「安心・安全・安定・信頼」できるインターネットサービスを さらに、Googleカレンダーに登録してみる • GcalAPI  というgem  を使う • カレンダーは、feed  という秘密の⽂文字列列で特定 • Googleアカウントのユーザ名とパスワード(アプリパス でもOK)も使う。 24
  30. 30. 「安心・安全・安定・信頼」できるインターネットサービスを gcalapiの簡単な使い方 25 require ‘gcakapi’ CAL_FEED = 'http://www.google.com/calendar/feeds/ XXXX@group.calendar.google.com/private/full' USER = 'kzrbeer@gmail.com' PASSWORD = 'hogehogehoge' service = GoogleCalendar::Service.new(USER, PASSWORD) cal = GoogleCalendar::Calendar.new(service, CAL_FEED) event = cal.create_event event.title = “イベントのタイトル” event.st = DateTime型のイベント開始時刻 event.end = DateTime型のイベント終了時刻 event.save!
  31. 31. 「安心・安全・安定・信頼」できるインターネットサービスを demo 26 ・Googleカレンダーに登録するデモ
  32. 32. 「安心・安全・安定・信頼」できるインターネットサービスを gcalgen gem のご紹介 27 • https://github.com/izawa/gcalgen • event,  every  の他にも、 • ⽉月頭最初の平⽇日  /  ⽉月末最後の平⽇日 • 休⽇日・祝⽇日だったら翌⽇日に延期 • ⽣生成するイベントの期間指定  などを記述可能。 •  gem  install  gcalgen   • でインストールできます。
  33. 33. 「安心・安全・安定・信頼」できるインターネットサービスを • Thank  You! • If  you  have  any  comments, • please  send  to: • Mail:  izawa@izawa.org  /  izawa@clwit.co.jp • Twitter:  @Yukimitsu_̲Izawa 28

×