Skip to content

Instantly share code, notes, and snippets.

@jnv
Last active December 29, 2015 23:59
Show Gist options
  • Save jnv/7746750 to your computer and use it in GitHub Desktop.
Save jnv/7746750 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"DSL"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Domain Specific Language"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## RSpec\n",
"\n",
"```ruby\n",
"it \"converts strings to money\" do\n",
" \"5 CZK\".to_money.should be_instance_of Money\n",
"end\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Sinatra\n",
"\n",
"```ruby\n",
"get '/hi' do\n",
" \"Hello World!\"\n",
"end\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Rails routing\n",
"\n",
"```ruby\n",
"resources :products do\n",
" resources :comments, :sales\n",
" resource :seller\n",
"end\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Chef\n",
"\n",
"```ruby\n",
"if platform_family?(\"rhel\")\n",
" pip_binary = \"/usr/bin/pip\"\n",
"else\n",
" pip_binary = \"/usr/local/bin/pip\"\n",
"end\n",
"\n",
"remote_file \"#{Chef::Config[:file_cache_path]}/distribute_setup.py\" do\n",
" source \"http://python-distribute.org/distribute_setup.py\"\n",
" mode \"0644\"\n",
" not_if { ::File.exists?(pip_binary) }\n",
"end\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"```ruby\n",
"turtle = Turtle.new\n",
"turtle.walk do\n",
" 3.times do\n",
" forward(8)\n",
" pen_down\n",
" 4.times do\n",
" forward(4)\n",
" left\n",
" end\n",
" pen_up\n",
" end\n",
"end\n",
"turtle.draw\n",
"```"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Quiz'em DSL"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```txt\n",
"Who was the first president of the USA?\n",
"1 - Fred Flintstone\n",
"2 - Martha Washington\n",
"3 - George Washington\n",
"4 - George Jetson\n",
"Enter your answer:\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small>Source: http://jroller.com/rolsen/entry/building_a_dsl_in_ruby</small>"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"```ruby\n",
"question 'Who was the first president of the USA?'\n",
"wrong 'Fred Flintstone'\n",
"wrong 'Martha Washington'\n",
"right 'George Washington'\n",
"wrong 'George Jetson'\n",
"\n",
"question 'Who is buried in Grant\\'s tomb?'\n",
"right 'U. S. Grant'\n",
"wrong 'Cary Grant'\n",
"wrong 'Hugh Grant'\n",
"wrong 'W. T. Grant'\n",
"```"
]
},
{
"cell_type": "heading",
"level": 3,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Global methods + singleton"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def question(text)\n",
" puts \"Just read a question: #{text}\"\n",
"end\n",
"\n",
"def right(text)\n",
" puts \"Just read a correct answer: #{text}\"\n",
"end\n",
"\n",
"def wrong(text)\n",
" puts \"Just read an incorrect answer: #{text}\"\n",
"end\n",
"\n",
"question 'Who is buried in Grant\\'s tomb?'\n",
"right 'U. S. Grant'\n",
"wrong 'Cary Grant'"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Just read a question: Who is buried in Grant's tomb?\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Just read a correct answer: U. S. Grant\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Just read an incorrect answer: Cary Grant\n"
]
}
],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"require 'singleton'\n",
"\n",
"class Quiz\n",
" include Singleton\n",
"\n",
" def initialize\n",
" reset\n",
" end\n",
" \n",
" def reset\n",
" @questions = []\n",
" end\n",
"\n",
" def add_question(question)\n",
" @questions << question\n",
" end\n",
"\n",
" def last_question\n",
" @questions.last\n",
" end\n",
"\n",
" def run!\n",
" count=0\n",
" @questions.each { |q| count += 1 if q.ask }\n",
" puts \"You got #{count} answers correct out of #{@questions.size}.\"\n",
" end\n",
"end"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Question\n",
"\n",
" # Just for example\n",
" def mock_gets\n",
" rand(@answers.size) + 1\n",
" end\n",
" \n",
" def initialize( text )\n",
" @text = text\n",
" @answers = []\n",
" end\n",
"\n",
" def add_answer(answer)\n",
" @answers << answer\n",
" end\n",
"\n",
" def ask\n",
" puts \"\"\n",
" puts \"Question: #{@text}\"\n",
" @answers.size.times do |i|\n",
" puts \"#{i+1} - #{@answers[i].text}\"\n",
" end\n",
" print \"Enter answer: \"\n",
" # answer = gets.to_i - 1\n",
" answer = mock_gets.to_i - 1\n",
" puts answer\n",
" return @answers[answer].correct\n",
" end\n",
"end"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Answer\n",
" attr_reader :text, :correct\n",
" def initialize( text, correct )\n",
" @text = text\n",
" @correct = correct\n",
" end\n",
"end"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def question(text)\n",
" Quiz.instance.add_question Question.new(text)\n",
"end\n",
"\n",
"def right(text)\n",
" Quiz.instance.last_question.add_answer Answer.new(text,true)\n",
"end\n",
"\n",
"def wrong(text)\n",
" Quiz.instance.last_question.add_answer Answer.new(text,false)\n",
"end\n"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"Quiz.instance.reset\n",
"question 'Who was the first president of the USA?'\n",
"wrong 'Fred Flintstone'\n",
"wrong 'Martha Washington'\n",
"right 'George Washington'\n",
"wrong 'George Jetson'\n",
"\n",
"question 'Who is buried in Grant\\'s tomb?'\n",
"right 'U. S. Grant'\n",
"wrong 'Cary Grant'\n",
"wrong 'Hugh Grant'\n",
"wrong 'W. T. Grant'\n",
"\n",
"Quiz.instance.run!"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Question: Who was the first president of the USA?\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 - Fred Flintstone\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"2 - Martha Washington\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3 - George Washington\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"4 - George Jetson\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Enter answer: "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Question: Who is buried in Grant's tomb?\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 - U. S. Grant\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"2 - Cary Grant\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3 - Hugh Grant\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"4 - W. T. Grant\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Enter answer: "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"You got 0 answers correct out of 2.\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "heading",
"level": 3,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"With block parameter"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"```ruby\n",
"quiz1 = QuizBuilder.new\n",
"quiz1.build do |q|\n",
" q.question 'What is a man?'\n",
" q.wrong 'An ape'\n",
" q.right 'A miserable little pile of secrets!'\n",
" q.wrong 'A cupcake'\n",
" q.wrong 'dunno lol'\n",
"end\n",
"quiz1.run!\n",
"```"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class QuizBuilder\n",
" def initialize\n",
" reset\n",
" end\n",
" \n",
" def reset\n",
" @questions = []\n",
" end\n",
"\n",
" def add_question(question)\n",
" @questions << question\n",
" end\n",
"\n",
" def last_question\n",
" @questions.last\n",
" end\n",
"\n",
" def run!\n",
" count=0\n",
" @questions.each { |q| count += 1 if q.ask }\n",
" puts \"You got #{count} answers correct out of #{@questions.size}.\"\n",
" end\n",
"end"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class QuizBuilder\n",
" def question(text)\n",
" add_question Question.new(text)\n",
" end\n",
"\n",
" def right(text)\n",
" last_question.add_answer Answer.new(text,true)\n",
" end\n",
"\n",
" def wrong(text)\n",
" last_question.add_answer Answer.new(text,false)\n",
" end\n",
"end"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class QuizBuilder\n",
" def build\n",
" yield self\n",
" end\n",
"end"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"quiz1 = QuizBuilder.new\n",
"quiz1.build do |q|\n",
" q.question 'What is a man?'\n",
" q.wrong 'An ape'\n",
" q.right 'A miserable little pile of secrets!'\n",
" q.wrong 'A cupcake'\n",
" q.wrong 'dunno lol'\n",
"end\n",
"quiz1.run!"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Question: What is a man?\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 - An ape\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"2 - A miserable little pile of secrets!\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3 - A cupcake\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"4 - dunno lol\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Enter answer: "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"You got 1 answers correct out of 1.\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "heading",
"level": 3,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Without block parameter"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"```ruby\n",
"quiz2 = QuizBuilder.new\n",
"quiz2.build do\n",
" question \"What's the universal answer to life the universe and everything?\"\n",
" wrong 'cupcakes'\n",
" wrong 'love'\n",
" right '42'\n",
" wrong 'Try and be nice to people, avoid eating fat, read a good book every now and then, get some walking in, and try and live together in peace and harmony with people of all creeds and nations.'\n",
"end\n",
"```"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class QuizBuilder\n",
" def build(&block)\n",
" instance_eval &block\n",
" end\n",
"end"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"quiz2 = QuizBuilder.new\n",
"quiz2.build do\n",
" question \"What's the universal answer to life the universe and everything?\"\n",
" wrong 'cupcakes'\n",
" wrong 'love'\n",
" right '42'\n",
" wrong 'Try and be nice to people, avoid eating fat, read a good book every now and then, get some walking in, and try and live together in peace and harmony with people of all creeds and nations.'\n",
"end\n",
"quiz2.run!"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Question: What's the universal answer to life the universe and everything?\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 - cupcakes\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"2 - love\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3 - 42\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"4 - Try and be nice to people, avoid eating fat, read a good book every now and then, get some walking in, and try and live together in peace and harmony with people of all creeds and nations.\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Enter answer: "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"You got 0 answers correct out of 1.\n"
]
}
],
"prompt_number": 12
},
{
"cell_type": "heading",
"level": 3,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Builder DSL"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"require 'builder'"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"text": [
"true"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"builder = Builder::XmlMarkup.new\n",
"xml = builder.person do |b|\n",
" b.name(\"Jim\")\n",
" b.phone(\"555-1234\")\n",
"end\n",
"\n",
"xml"
],
"language": "ruby",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 15,
"text": [
"\"<person><name>Jim</name><phone>555-1234</phone></person>\""
]
}
],
"prompt_number": 15
},
{
"cell_type": "heading",
"level": 2,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Exersise: Turtle DSL"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Implement Turtle Graphics DSL. Turtle class understands following commands:\n",
"\n",
"```ruby\n",
"class Turtle\n",
" def left; ... end\n",
" def right; ... end\n",
" def forward(n); ... end\n",
" def pen_up; .. end\n",
" def pen_down; ... end\n",
" def walk(...); end\n",
" def draw; ... end\n",
"end\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"```ruby\n",
"turtle = Turtle.new\n",
"turtle.walk do\n",
" 3.times do\n",
" forward(8)\n",
" pen_down\n",
" 4.times do\n",
" forward(4)\n",
" left\n",
" end\n",
" pen_up\n",
" end\n",
"end\n",
"turtle.draw\n",
"```"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Resources"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* http://jroller.com/rolsen/entry/building_a_dsl_in_ruby\n",
"* http://jroller.com/rolsen/entry/building_a_dsl_in_ruby1\n",
"* http://blog.joecorcoran.co.uk/2013/09/04/simple-pattern-ruby-dsl/"
]
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment