Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

MI L'ANIMA

Slide 3

Slide 3 text

WHY DO WE LOVE RUBY?

Slide 4

Slide 4 text

EASY TO READ

Slide 5

Slide 5 text

COMMUNITY ▸ 100k+ gem on rubygems.org ▸ 3rd repo language on GitHub1 1 according to GitHub Language Trends

Slide 6

Slide 6 text

RUBY ISN'T COOL ANYMORE AND WE ARE FINE WITH THAT.

Slide 7

Slide 7 text

TESTING CULTURE

Slide 8

Slide 8 text

RUBY ON RAILS

Slide 9

Slide 9 text

ALL THAT GLITTERS IS NOT GOLD

Slide 10

Slide 10 text

RUBY IS SLOW BUT RUBY 2.0 HAS MADE GOOD PROGRESS 2 2 Garbage collection in ruby 2.0

Slide 11

Slide 11 text

NOT SUITED FOR PARALLELISM 3 3 MRI have GIL lock, JRuby doesn't. More about GIL.

Slide 12

Slide 12 text

CODING TIME

Slide 13

Slide 13 text

DSL DOMAIN-SPECIFIC LANGUAGE

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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!"

Slide 17

Slide 17 text

module RecipeBook @collection = {} def self.add(recipe) @collection[recipe.name] = recipe end def self.get(name) @collection[name] end end

Slide 18

Slide 18 text

recipe = Recipe.new recipe.name = "spaghetti con polpette" [...] RecipeBook.add(recipe) RecipeBook.get("spaghetti con polpette").cook! "Cooking [...]"

Slide 19

Slide 19 text

WE WANT THIS RecipeBook.add do name "Spaghetti con polpette" difficulty :easy ingredient "spaghetti" ingredient "passata di pomodoro" ingredient "polpette" end

Slide 20

Slide 20 text

ATTEMPT #1

Slide 21

Slide 21 text

module RecipeBook [...] def self.add(&block) recipe = Recipe.new recipe.instance_eval(&block) @collection[recipe.name] = recipe end [...] end

Slide 22

Slide 22 text

RecipeBook.add do self.name = "spaghetti con polpette" self.difficulty = :easy add_ingredient("spaghetti") add_ingredient("passata di pomodoro") add_ingredient("polpette") end

Slide 23

Slide 23 text

UGLY !

Slide 24

Slide 24 text

WE WANT THIS! RecipeBook.add do name "Spaghetti con polpette" difficulty :easy ingredient "spaghetti" ingredient "passata di pomodoro" ingredient "polpette" end

Slide 25

Slide 25 text

ATTEMPT #2

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

RecipeBook.add do name("spaghetti con polpette") difficulty(:easy) ingredient("spaghetti") ingredient("passata di pomodoro") ingredient("polpette") end

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

!

Slide 31

Slide 31 text

REFACTORING

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

BOOKS ▸ Practical Object-Oriented Design in Ruby ▸ Metaprogramming Ruby 2

Slide 35

Slide 35 text

QUESTIONS TIME

Slide 36

Slide 36 text

VI È VENUTA FAME? SOURCE CODE: HTTP://BIT.LY/1NWGAJT @delphaber @welaika