Defining DSL in Ruby

Defining DSL in Ruby

4cf300db4be834dfb4ddd76337205946?s=128

Michał Poczwardowski

June 17, 2015
Tweet

Transcript

  1. 4.

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

    EXTERNAL • own parser/lexer/syntactic tree • examples: SQL
  2. 6.

    Why? • easy to read • easy to use by

    non-programmers • in Ruby… easy to implement!
  3. 7.

    Potential project • DSL for defining online surveys • All

    questions specified just using a DSL instead of complicated forms
  4. 8.

    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. 9.
  6. 10.
  7. 11.

    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
  8. 12.

    QuestionBuilder class QuestionBuilder def text(content) @text = content end def

    answer_option(label) @answer_options << label end end
  9. 13.

    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
  10. 14.

    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 "
  11. 16.

    docile gem Docile turns any Ruby object into a DSL.

    Especially useful with the Builder pattern.
  12. 17.

    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
  13. 19.