Опыт создания DSL на Ruby.Где применить, как готовить исколько добавитьметапрограммирования.Антон Сидельниковndmeredian@gm...
Содержание• О самой концепции DSL• Чем Ruby хорош для DSL• Использование Ruby-based DSL в  реальных проектах• Ruby-based D...
Предметно-ориентированный язык(Domain Specific Language)• Предназначен для решения узкого  круга задач• Понятия предметной...
Как можно применить DSL•   Конфиги (apache, etc.), Make•   Языки описания данных (HTML, TeX)•   Язык описания правил (ipfw...
Использование DSL             Pro                            Contra•Повышение уровня абстракции     •Расходы на создание и...
Два подхода к созданию DSL           External                          Internal•Придумываем грамматику            •Выбирае...
Ruby-based DSL• Internal DSL       • Поддерка IDE       • Доступ к Ruby gems и прочему         существующему коду• Еще бол...
Person bender = new Person("Bender"); bender.wish("lunapark", new HashMap<String, String[]>() {{ put(“with", new String[]{...
“По моему опыту, большинство грамотнонаписанных на Ruby программ уже являются DSL – просто по природе синтаксиса Ruby.”   ...
Простой пример                                                          Перепиши мне                                      ...
Простой пример                                                   Перепиши мне                                             ...
Жизненный примерmonkey – язык для функциональноготестирования промышленныхэнергетических сетей.Основные функции:  • Описан...
Исходная инфраструктурасистемы•   Система управления сетями, написанная на    Java•   Доступ к данным через удаленную SQL-...
Исходная ситуация с                тестированием                                                  А как нам писать        ...
Решение: JRuby(в других условиях здесь могли бы быть С-Ruby,    IronRuby, а может и другие языки, например Scala    или Cl...
JRuby• Выполняется на JVM• Прямая работа с Java-объектами через  публичные интерфейсы• Контроль результатов и сбор данных ...
Результат                   Сервер       Java Core               SQL-базаЗапросы к     Сбор данных       Методы анализа  я...
РезультатTestTouCostOneDay = testcase(MockBaseTestCase, TestTouCostOneDay) {        request categorizedMetricDataRequest(s...
Как подойти к созданию       Ruby-DSL?                         19
DSL Roadmap•   Начните с фиксации предполагаемого DSL в    виде валидного Ruby-синтаксиса•   Не увлекайтесь моделью – все ...
DSL Roadmap• Используйте Test-Driven Development – это  естественный способ опробовать язык до того,  как он окончательно ...
DSL Roadmap• Разберитесь с тем, что может, и что не может  Ruby. Метапрограммирование является  основой создания DSL.• Убе...
DSL Roadmap• Минимизируйте зашумленность языка• Используйте syntax sugar:      • опциональные скобки и терминальные       ...
DSL Roadmap•   Зафиксируйте модель, когда вы целиком    разобрались с внешним видом языка•   Наведите порядок, проведите р...
Дополнительная          информация:•   Книга “Metaprogramming Ruby” из серии “The Pragmatic    Bookshelf”•   http://rubyco...
О чем это все было?• Существуют случаи, когда использование DSL  оправдано• Динамические языки позволяют сравнительно  деш...
Вопросы?Сидельников Антонndmeredian@gmail.com+7(923)114-5551                       27
Upcoming SlideShare
Loading in …5
×

CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как готовить и сколько добавить метапрограммирования

1,128 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,128
On SlideShare
0
From Embeds
0
Number of Embeds
224
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как готовить и сколько добавить метапрограммирования

  1. 1. Опыт создания DSL на Ruby.Где применить, как готовить исколько добавитьметапрограммирования.Антон Сидельниковndmeredian@gmail.com
  2. 2. Содержание• О самой концепции DSL• Чем Ruby хорош для DSL• Использование Ruby-based DSL в реальных проектах• Ruby-based DSL Roadmap 2
  3. 3. Предметно-ориентированный язык(Domain Specific Language)• Предназначен для решения узкого круга задач• Понятия предметной области являются элементарными• Задачи решаются в терминах предметной области 3
  4. 4. Как можно применить DSL• Конфиги (apache, etc.), Make• Языки описания данных (HTML, TeX)• Язык описания правил (ipfw)• Язык для написания тестов• Высокоуровневый язык для написания бизнес-логики 4
  5. 5. Использование DSL Pro Contra•Повышение уровня абстракции •Расходы на создание и•Более явная логика кода поддержку языка•Повышение скорости разработки •Область применения действительно мала•Можно передать управление не-программисту •Требует обучения пользователя 5
  6. 6. Два подхода к созданию DSL External Internal•Придумываем грамматику •Выбираем язык по вкусу•Пишем интерпретатор... •Используем синтаксис и•…транслятор... семантику старого языка для•...или компилятор (если скучно) создания иллюзии нового 6
  7. 7. Ruby-based DSL• Internal DSL • Поддерка IDE • Доступ к Ruby gems и прочему существующему коду• Еще большая скорость разработки• Гибкий синтаксис, обилие syntax sugar• Развитая система метарограммирования• Возможность интеграции с другими языками 7
  8. 8. Person bender = new Person("Bender"); bender.wish("lunapark", new HashMap<String, String[]>() {{ put(“with", new String[]{"blackjack", "hookers"} ); }}); bender.wish("death", new HashMap<String, String[]>() {{ put("to_all", new String[]{"humans"} ); }); bender = Person.new Bender bender.wishes :lunapark, :with => [:blackjack, :hookers] bender.wishes :death, :to_all => :humansBender.wishes { lunapark with blackjack, hookers death to_all humans} 8
  9. 9. “По моему опыту, большинство грамотнонаписанных на Ruby программ уже являются DSL – просто по природе синтаксиса Ruby.” - Jamis Buck, 37 signals 9
  10. 10. Простой пример Перепиши мне конфиг, а то я тут ничего не понимаю..!<?xml version="1.0" encoding="UTF-8" standalone="no"?><repository> <solver class="implementation.solvers.SempSolver"> <setup> <param type="string" name="SOLVER_HOME">"~/.wine/drive_c/semp/"</param> </setup> <method name="EfficiencyTrendAnalysis" input="reflexive"> <param type="string"name="MODULE_PATH">"modules/EfficiencyTrendAnalysis/"<param> ... </method> ... </solver></repository> 10
  11. 11. Простой пример Перепиши мне конфиг, а то я тут ничего не понимаю..!require reposolver("implementation.solvers.SempSolver") { SOLVER_HOME = "~/.wine/drive_c/semp/" MODULES_HOME = File.join SOLVER_HOME, "modules" method { name "EfficiencyTrendAnalysis" Сам перепиши! MODULE_PATH = File.join MODULES_HOME, name }} 11
  12. 12. Жизненный примерmonkey – язык для функциональноготестирования промышленныхэнергетических сетей.Основные функции: • Описание тест-кейсов • Сбор статистики • Анализ результатов исполнения тест- кейсов 12
  13. 13. Исходная инфраструктурасистемы• Система управления сетями, написанная на Java• Доступ к данным через удаленную SQL-базу• Надо тестировать код на mockup-системах• Нужен контроль состояния работающих систем 13
  14. 14. Исходная ситуация с тестированием А как нам писать функциональные тесты для диагностики СерверОкей, вот вам работающи систем? WebAPI Java Core SQL-база WebAPI SSH-доступ А тесты на PHP писать?! 14
  15. 15. Решение: JRuby(в других условиях здесь могли бы быть С-Ruby, IronRuby, а может и другие языки, например Scala или Clojure) 15
  16. 16. JRuby• Выполняется на JVM• Прямая работа с Java-объектами через публичные интерфейсы• Контроль результатов и сбор данных напрямую из SQL-базы• Обработка данных и анализ результатов на стороне Ruby• Быстро и эффективно 16
  17. 17. Результат Сервер Java Core SQL-базаЗапросы к Сбор данных Методы анализа ядру из БД данных Ruby DSL-framework А где PHP, к которому мы уже привыкли?! 17
  18. 18. РезультатTestTouCostOneDay = testcase(MockBaseTestCase, TestTouCostOneDay) { request categorizedMetricDataRequest(subscriber, sdp) { metric(Cost) granularity(DAY) interval(accountInterval.start, accountInterval.start) timezone("PST") } validate { granularity.should == DAY processor(TouProcessor).cost.should be_granular_limited dpAccount.servicePlan.costLimit }} 18
  19. 19. Как подойти к созданию Ruby-DSL? 19
  20. 20. DSL Roadmap• Начните с фиксации предполагаемого DSL в виде валидного Ruby-синтаксиса• Не увлекайтесь моделью – все равно её переделывать• Сразу подумайте о том, как вы хотите соединить DSL с существующей средой 20
  21. 21. DSL Roadmap• Используйте Test-Driven Development – это естественный способ опробовать язык до того, как он окончательно создан• Ведите разработку малыми итерациями• Согласуйте вид DSL с экспертом предметной области, если сами им не являетесь 21
  22. 22. DSL Roadmap• Разберитесь с тем, что может, и что не может Ruby. Метапрограммирование является основой создания DSL.• Убедитесь, что знаете все эти слова: • eval, instance_eval и class_eval • define_method и alias_method • method_missing и const_missing • Open class(1.8) или Refinements (1.9)• Но повторяю – не увлекайтесь моделью! 22
  23. 23. DSL Roadmap• Минимизируйте зашумленность языка• Используйте syntax sugar: • опциональные скобки и терминальные символы • символы вместо строк • блоки • литеральные массивы и хэши • группировка аргументов 23
  24. 24. DSL Roadmap• Зафиксируйте модель, когда вы целиком разобрались с внешним видом языка• Наведите порядок, проведите рефакторинг 24
  25. 25. Дополнительная информация:• Книга “Metaprogramming Ruby” из серии “The Pragmatic Bookshelf”• http://rubyconf2008.confreaks.com/advanced-dsls-in-ruby.html• http://obiefernandez.com/presentations/obie_fernandez-agile_d• Martin Fowler “Domain Specific Languages” 25
  26. 26. О чем это все было?• Существуют случаи, когда использование DSL оправдано• Динамические языки позволяют сравнительно дешево получать это преимущество• Современные языки можно интегрировать в широкий класс промышленных проектов• Лучший способ оценить плюсы и минусы – попробовать 26
  27. 27. Вопросы?Сидельников Антонndmeredian@gmail.com+7(923)114-5551 27

×