Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Defining DSL in Ruby

Defining DSL in Ruby

Avatar for Michał Poczwardowski

Michał Poczwardowski

June 17, 2015
Tweet

More Decks by Michał Poczwardowski

Other Decks in Programming

Transcript

  1. DSL INTERNAL • just embedded in GPL (General Purpose Language)

    EXTERNAL • own parser/lexer/syntactic tree • examples: SQL
  2. Why? • easy to read • easy to use by

    non-programmers • in Ruby… easy to implement!
  3. Potential project • DSL for defining online surveys • All

    questions specified just using a DSL instead of complicated forms
  4. Survey DSL 01: survey :trug_questions do 02: title 'A few

    questions about TRUG' 03: question :city, kind: :single_choice do 04: text 'Where do you live?' 05: answer_option :gdansk 06: answer_option :gdynia 07: answer_option :sopot 08: end 09: end
  5. Question + QuestionBuilder Question = Struct.new(:text, :answer_options) class QuestionBuilder def

    initialize @text = 'Unset Text' @answer_options = [] end def build Question.new(@text, @answer_options) end end
  6. QuestionBuilder class QuestionBuilder def text(content) @text = content end def

    answer_option(label) @answer_options << label end end
  7. instance_eval def build_question(&block) builder = QuestionBuilder.new builder.instance_eval(&block) builder.build end build_question

    do text 'Where do you live?' answer_option :gdansk answer_option :gdynia answer_option :sopot end
  8. It may be a string def build_question(dsl_string) builder = QuestionBuilder.new

    builder.instance_eval(dsl_string) builder.build end build_question " text 'Where do you live?' answer_option :gdansk answer_option :gdynia answer_option :sopot "
  9. docile gem Docile turns any Ruby object into a DSL.

    Especially useful with the Builder pattern.
  10. docile gem 01: with_array([]) do 02: push 1 03: push

    2 04: pop 05: push 3 06: end #=> [1, 3] def with_array(arr=[], &block) Docile.dsl_eval(arr, &block) end