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

Mi Ruby l'anima

weLaika
October 26, 2015

Mi Ruby l'anima

The love for Ruby and metaprogramming with DSLs

weLaika

October 26, 2015
Tweet

More Decks by weLaika

Other Decks in Technology

Transcript

  1. COMMUNITY ▸ 100k+ gem on rubygems.org ▸ 3rd repo language

    on GitHub1 1 according to GitHub Language Trends
  2. RUBY IS SLOW BUT RUBY 2.0 HAS MADE GOOD PROGRESS

    2 2 Garbage collection in ruby 2.0
  3. NOT SUITED FOR PARALLELISM 3 3 MRI have GIL lock,

    JRuby doesn't. More about GIL.
  4. DSL [...] a computer language that's targeted to a particular

    kind of problem, rather than a general purpose language that's aimed at any kind of software problem.4 — Martin Fowler 4 Martin Fowler article
  5. class Recipe attr_accessor :name, :ingredients, :difficulty # defines getters and

    setters def initialize @ingredients = [] end def add_ingredient(ingredient) ingredients << ingredient end def cook! puts "Cooking #{name} (#{difficulty})," puts "with: #{ingredients.join(", ")}." puts "Buon appetito!" end end
  6. recipe = Recipe.new recipe.name = "spaghetti con polpette" recipe.difficulty =

    :easy recipe.add_ingredient("spaghetti") recipe.add_ingredient("polpa di pomodoro") recipe.add_ingredient("polpette") recipe.cook! "Cooking spaghetti con polpette (easy), with: spaghetti, polpa di pomodoro, polpette. Buon appetito!"
  7. recipe = Recipe.new recipe.name = "spaghetti con polpette" [...] RecipeBook.add(recipe)

    RecipeBook.get("spaghetti con polpette").cook! "Cooking [...]"
  8. WE WANT THIS RecipeBook.add do name "Spaghetti con polpette" difficulty

    :easy ingredient "spaghetti" ingredient "passata di pomodoro" ingredient "polpette" end
  9. RecipeBook.add do self.name = "spaghetti con polpette" self.difficulty = :easy

    add_ingredient("spaghetti") add_ingredient("passata di pomodoro") add_ingredient("polpette") end
  10. WE WANT THIS! RecipeBook.add do name "Spaghetti con polpette" difficulty

    :easy ingredient "spaghetti" ingredient "passata di pomodoro" ingredient "polpette" end
  11. class RecipeBuilder attr_reader :recipe def initialize @recipe = Recipe.new end

    def name(name) recipe.name = name end def difficulty(difficulty) recipe.difficulty = difficulty end def ingredient(ingredient) recipe.add_ingredient(ingredient) end end
  12. module RecipeBook @collection = {} def self.add(&block) builder = RecipeBuilder.new

    builder.instance_eval(&block) recipe = builder.recipe @collection[recipe.name] = recipe end def self.get(name) @collection[name] end end
  13. RecipeBook.add do name "spaghetti con polpette" difficulty :easy ingredient "spaghetti"

    ingredient "passata di pomodoro" ingredient "polpette" end
  14. !

  15. class RecipeBuilder attr_reader :recipe def initialize @recipe = Recipe.new end

    def name(name) recipe.name = name end def difficulty(difficulty) recipe.difficulty = difficulty end def ingredient(ingredient) recipe.add_ingredient(ingredient) end end
  16. class RecipeBuilder attr_reader :recipe DELEGATED_SETTERS = [:name, :difficulty] def initialize

    @recipe = Recipe.new end def method_missing(method_name, *args) if DELEGATED_SETTERS.include?(method_name) recipe.send("#{method_name}=", *args) # e.g.: name=("spaghetti con polpette") else super end end def ingredient(ingredient) recipe.add_ingredient(ingredient) end end