SlideShare a Scribd company logo
1 of 78
Download to read offline
“ Genius is the gold in the mine; talent is
  the miner who works and brings it out. ”
 Lady Marguerite Blessington




                                        Donets Basin
                                        Mina de carvão-Ucrânia
@akitaonrails

      Ruby e Ruby on Rails - 2006

Rails Summit Latin America - 2008

           RubyConf Brasil - 2010
Patterns e
         Anti-Patterns
         em Ruby
Fabio Akita (@akitaonrails)
Pattern   PADRÃO
STANDARD


 Pattern   PADRÃO


 Default
“Pattern”
“Standard”
Christopher Alexander
"...each pattern represents our current best
guess ... to solve the problem presented. ..., the
patterns are still hypotheses, all ... of them -and
are therefore all tentative, all free to evolve under
the impact of new experience and observation"

                 —Christopher Alexander, A Pattern Language, p. xv
require 'erubis'

 def render_erb(filepath)
   content = File.read(filepath)
   template = Erubis::Eruby.new(content)
   context = { title: "Hello World",
     paragraph: "This is an ERB template." }
   output = template.evaluate(context)
 end

 puts render_erb("sample.erb")




ERB
<html>
   <head><title><%= @title %></title></head>
   <body>
     <p><%= @paragraph %></p>
   </body>
 </html>




 <html>
   <head><title>Hello World</title></head>
   <body>
     <p>This is an ERB template.</p>
   </body>
 </html>




ERB
require 'rdiscount'

 def render_markdown(filepath)
   content = File.read(filepath)
   template = RDiscount.new(content)
   output = template.to_html
 end

 puts render_markdown("sample.md")




Markdown
# Hello World

 This is a Markdown example

 * [Markdown](http://daringfireball.net/projects/markdown/
 syntax/)




 <h1>Hello World</h1>

 <p>This is a Markdown example</p>

 <ul>
 <li><a href="http://daringfireball.net/projects/markdown/
 syntax/">Markdown</a></li>
 </ul>

Markdown
def render(filepath)
  case filepath
  when /erb$/ then render_erb(filepath)
  when /md$/ then render_markdown(filepath)
  when /sass$/ then render_sass(filepath)
  ...
  end
end

puts render("sample.erb")
Strategy
ENGINE                       FILE EXTENSIONS           REQUIRED LIBRARIES
  --------------------------   -----------------------   ----------------------------
  ERB                          .erb, .rhtml              none (included ruby stdlib)
  Interpolated String          .str                      none (included ruby core)
  Erubis                       .erb, .rhtml, .erubis     erubis
  Haml                         .haml                     haml
  Sass                         .sass                     haml (< 3.1) or sass (>= 3.1)
  Scss                         .scss                     haml (< 3.1) or sass (>= 3.1)
  Less CSS                     .less                     less
  Builder                      .builder                  builder
  Liquid                       .liquid                   liquid
  RDiscount                    .markdown, .mkd, .md      rdiscount
  Redcarpet                    .markdown, .mkd, .md      redcarpet
  BlueCloth                    .markdown, .mkd, .md      bluecloth
  Kramdown                     .markdown, .mkd, .md      kramdown
  Maruku                       .markdown, .mkd, .md      maruku
  RedCloth                     .textile                  redcloth
  RDoc                         .rdoc                     rdoc
  Radius                       .radius                   radius
  Markaby                      .mab                      markaby
  Nokogiri                     .nokogiri                 nokogiri
  CoffeeScript                 .coffee                   coffee-script (+ javascript)
  Creole (Wiki markup)         .wiki, .creole            creole
  WikiCloth (Wiki markup)      .wiki, .mediawiki, .mw    wikicloth
  Yajl                         .yajl                     yajl-ruby




Template Engines supported by Tilt
require 'tilt'

  template = Tilt.new("sample.erb")
  context = { title: "Hello World",
    paragraph: "This is an ERB template." }
  output = template.render(context)

  puts output

  template = Tilt.new("sample.md")
  output = template.render

  puts output




ERB and Markdown through Tilt
require 'tilt'

  template = Tilt::ErubisTemplate.new("sample.erb")
  context = { title: "Hello World",
    paragraph: "This is an ERB template." }
  output = template.render(context)

  puts output

  template = Tilt::RDiscountTemplate.new("sample.md")
  output = template.render

  puts output




Same example as previously
module Tilt
     ...
     @preferred_mappings = Hash.new
     @template_mappings = Hash.new { |h, k| h[k] = [] }

     # Hash of template path pattern => template implementation class mappings.
     def self.mappings
       @template_mappings
     end
     ...

     # Register a template implementation by file extension.
     def self.register(template_class, *extensions)
       if template_class.respond_to?(:to_str)
         # Support register(ext, template_class) too
         extensions, template_class = [template_class], extensions[0]
       end

       extensions.each do |ext|
         ext = normalize(ext)
         mappings[ext].unshift(template_class).uniq!
       end
     end
     ...

tilt.rb
require 'tilt/string'
  register StringTemplate, 'str'

  require 'tilt/erb'
  register ERBTemplate,    'erb', 'rhtml'
  register ErubisTemplate, 'erb', 'rhtml', 'erubis'

  require 'tilt/haml'
  register HamlTemplate,   'haml'

  require 'tilt/css'
  register SassTemplate, 'sass'
  register ScssTemplate, 'scss'
  register LessTemplate, 'less'

  ...



Tilt#register
> Tilt["erb"]
  => Tilt::ErubisTemplate

  > Tilt["md"]
  => Tilt::RDiscountTemplate

  > Tilt["haml"]
  => Tilt::HamlTemplate

  > Tilt['coffee']
  => Tilt::CoffeeScriptTemplate




Tilt#[]
module Tilt
    ...
    # Create a new template for the given
    # file using the file's extension
    # to determine the the template mapping.
    def self.new(file, line=nil, options={}, &block)
      if template_class = self[file]
        template_class.new(file, line, options, &block)
      else
        fail "No template engine registered for
  #{File.basename(file)}"
      end
    end




Tilt overrided #new
Factory
module Tilt
    # Base class for template implementations.
    # Subclasses must implement the #prepare method and one
    # of the #evaluate or #precompiled_template methods.
    class Template
      ...
      def render(scope=Object.new, locals={}, &block)
        evaluate scope, locals || {}, &block
      end

    protected
      def prepare; ... end
      def evaluate(scope, locals, &block); ... end
      def precompiled(locals); ... end
      def precompiled_template(locals); ... end
      def precompiled_preamble(locals); ... end
      def precompiled_postamble(locals); ''; end
      def compiled_method(locals_keys); ... end
    end
  end

Tilt::Template Lint
module Tilt
    # RedCloth implementation. See:
    # http://redcloth.org/
    class RedClothTemplate < Template
      def self.engine_initialized?
        defined? ::RedCloth
      end

      def initialize_engine
        require_template_library 'redcloth'
      end

      def prepare
        @engine = RedCloth.new(data)
        @output = nil
      end

      def evaluate(scope, locals, &block)
        @output ||= @engine.to_html
      end
    end
  end




Tilt::RedClothTemplate Implementation
Adapter
Rails         Mongrel




         Sinatra     CGI    Thin




        Ramaze             Webrick



Simple Web
Rails         Mongrel




         Sinatra     CGI    Thin




        Ramaze             Webrick



Simple Web
Rails          Mongrel




         Sinatra     Rack
                     CGI     Thin




        Ramaze              Webrick



Simple Web
class HelloWorld
    def call(env)
      [200,
        {"Content-Type" => "text/plain"},
        ["Hello world!"]]
    end
  end

  hello_world = ->(env) {
    [200,
      {"Content-Type" => "text/plain"},
      ["Hello world!"]]
  }




Minimal Rack Compliant
hello_world = ->(env) {
    [200,
      {"Content-Type" => "text/html"},
      ["<h1>Hello world!</h1>"]]
  }

  use Rack::ContentType, "text/html"
  use Rack::ShowExceptions
  use Rack::Auth::Basic, "Rack Demo" do |username, password|
    'secret' == password
  end

  # Setup Rack
  run Rack::URLMap.new( {
    "/hello" => hello_world,
    "/" => Rack::File.new( "index.html" )
  } )


rackup app.ru
module Rack
    class ContentType
      include Rack::Utils

      def initialize(app, content_type = "text/html")
        @app, @content_type = app, content_type
      end

      def call(env)
        status, headers, body = @app.call(env)
        headers = Utils::HeaderHash.new(headers)

        unless STATUS_WITH_NO_ENTITY_BODY.include?(status)
          headers['Content-Type'] ||= @content_type
        end

        [status, headers, body]
      end
    end
  end

rackup app.ru
use   ActionDispatch::Static
  use   Rack::Lock
  ...
  use   Rack::Runtime
  use   Rack::MethodOverride
  use   ActionDispatch::RequestId
  use   Rails::Rack::Logger
  use   ActionDispatch::ShowExceptions
  use   ActionDispatch::DebugExceptions
  use   ActionDispatch::RemoteIp
  use   ActionDispatch::Reloader
  use   ActionDispatch::Callbacks
  use   ActiveRecord::ConnectionAdapters::ConnectionManagement
  use   ActiveRecord::QueryCache
  use   ActionDispatch::Cookies
  use   ActionDispatch::Session::CookieStore
  use   ActionDispatch::Flash
  use   ActionDispatch::ParamsParser
  use   ActionDispatch::Head
  use   Rack::ConditionalGet
  use   Rack::ETag
  use   ActionDispatch::BestStandardsSupport
  use   Warden::Manager
  use   OmniAuth::Strategies::Twitter
  use   OmniAuth::Strategies::Facebook
  run   Rubyconf2012::Application.routes


rake middleware (Rails)
Chain of Responsibility
class Relationship
  attr_accessor :state

  def initialize
    @state = :dating
  end

  def get_married
    make_vows
    @state = :married
    eat_wedding_cake
  end

  def get_divorced
    @state = :divorced
  end

  def make_vows; "I do"; end
  def eat_wedding_cake; "Yummy"; end
end
class Relationship
  attr_accessor :state

  def initialize
    @state = :dating
  end

  def get_married
    raise "Must date before marry" unless @state == :dating
    make_vows
    @state = :married
    eat_wedding_cake
  end

  def get_divorced
    raise "Must be married before divorce" unless @state == :married
    @state = :divorced
  end

  def make_vows; "I do"; end
  def eat_wedding_cake; "Yummy"; end
end
class Relationship
  include AASM

  aasm do
    state :dating, initial: true
    state :married
    state :divorced

    event :get_married,
          :before => :make_vows,
          :after => :eat_wedding_cake do
      transitions from: [:dating], to: :married
    end

    event :get_divorced do
      transitions from: [:married], to: :divorced
    end
  end

  def make_vows; "I do"; end
  def eat_wedding_cake; "Yummy"; end
end
class Relationship
  attr_accessor :dating, :married, :divorced

  def initialize
    @dating, @married, @divorced = true, false, false
  end

  def get_married
    raise "Must date before marry" unless dating
    make_vows
    @dating, @married = false, true
    eat_wedding_cake
  end

  def get_divorced
    raise "Must be married before divorce" unless married
    @married, @divorced = false, true
  end

  def make_vows; "I do"; end
  def eat_wedding_cake; "Yummy"; end
end
State
class SaleOrder
  attr_accessor :items, :value, :checkout_date
  def initialize(*args)
    @items, @value, @checkout_date = args
  end
end

sale = SaleOrder.new(
  ['Biscuit', 'Cheese'], 15.0, "2012-07-07")
require 'money'
require 'time'
class SaleOrder
  attr_reader :value, :checkout_date
  def initialize(options = {})
    @items, @value, @checkout_date = [], Money.new(0.0, "USD"), nil
    self.items = options[:items] || []
    self.value = options[:value] || 0.0
    self.checkout_date = options[:checkout_date]
  end
  def items=(items); @items += items.dup; end
  def items(index); @items[index]; end
  def value=(value); @value = Money.new(value.to_f, "USD"); end
  def checkout_date=(date)
    @checkout_date = Date.parse(date) if date
  end
end

sale = SaleOrder.new(items: ['Biscuit', 'Cheese'],
  value: 15.0, checkout_date: "2012-07-07")
Primitive Obsession
def slug(title)
    # 1
    if title.nil?
      title.strip.downcase.tr_s('^[a-z0-9]', '-')
    end

     # 2
     title.strip.downcase.tr_s('^[a-z0-9]', '-') if title

     # 3
     (title || "").strip.downcase.tr_s('^[a-z0-9]', '-')

    # 4
    title.strip.downcase.tr_s('^[a-z0-9]', '-') rescue nil
  end




http:/
     /u.akita.ws/avdi-null
class Object
    def try(*a, &b)
      if a.empty? && block_given?
        yield self
      else
        public_send(*a, &b)
      end
    end
  end

  class NilClass
    def try(*args)
      nil
    end
  end




ActiveSupport - Try
require 'active_support/core_ext/object/try'

  def slug(title)
    title.try(:strip).try(:downcase).
      try(:tr_s, '^[a-z0-9]', '-')
  end




  <%= title ? title.downcase : "" %>

  <%= title.try(:downcase) %>




http:/
     /u.akita.ws/avdi-null
class NullObject
    def method_missing(*args, &block)
      self
    end

    def   to_a;   []; end
    def   to_s;   ""; end
    def   to_f;   0.0; end
    def   to_i;   0; end
                               def Maybe(value)
                                 value.nil? ? NullObject.new : value
    def tap; self; end
                               end
    def to_value; nil; end
  end
                               class Object
                                 def to_value
                                   self
                                 end
                               end




http:/
     /u.akita.ws/avdi-null
def slug(title)
    Maybe(title).strip.downcase.tr_s('^[a-z0-9]', '-')
  end

  def slug(title)
    title = Maybe(title)
    if title.to_value
      # do something useful
    end
    title.strip.downcase.tr_s('^[a-z0-9]', '-')
  end




http:/
     /u.akita.ws/avdi-null
git clone git://github.com/akitaonrails/null.git
  cd null
  gem build null.gemspec
  gem install null-0.1.gem

  > require 'null'
  > Maybe(someobj).foo.bar.something
  #=> null

  > (100.0 / (NULL * 15.5) - 150)
  #=> null

  object = Maybe(someobj)
  if object.truthy?
    # something useful
  end



http:/
     /u.akita.ws/avdi-null
Null Object
class SalesOrder < Struct.new(:products, :total, :buyer_name)
  def html_receipt
    html_items = products.inject("") do |html, item|
      html += "<li>#{item}</li>"
    end

    html = %{<h1>Thanks for the Purchase #{buyer_name}!</h1>
      <p>You purchased:</p>
      <ul>
      #{html_items}
      </ul>
      <p>Total: $#{total}</p>}
  end
end

order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" )
> order.html_receipt

=> "<h1>Thanks for the Purchase John Doe!</h1>
    <p>You purchased:</p>
    <ul>
    <li>Bacon</li><li>Cheese</li>
    </ul>
    <p>Total: $10.0</p>"
class SalesOrder < Struct.new(:products, :total, :buyer_name)
  def html_receipt
    html_items = products.inject("") do |html, item|
      html += "<li>#{item}</li>"
    end

    html = %{<h1>Thanks for the Purchase #{buyer_name}!</h1>
      <p>You purchased:</p>
      <ul>
      #{html_items}
      </ul>
      <p>Total: $#{total}</p>}
  end
end

order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" )
class SalesOrder < Struct.new(:products, :total, :buyer_name)
end

class SalesOrderDecorator < SimpleDelegator
  def html_receipt
    html_items = products.inject("") do |html, item|
      html += "<li>#{item}</li>"
    end

    html = %{<h1>Thanks for the Purchase #{buyer_name}!</h1>
      <p>You purchased:</p>
      <ul>
      #{html_items}
      </ul>
      <p>Total: $#{total}</p>}
  end
end

order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" )
decorated_order = SalesOrderDecorator.new(order)
> decorated_order.html_receipt

=> "<h1>Thanks for the Purchase John Doe!</h1>
    <p>You purchased:</p>
    <ul>
    <li>Bacon</li><li>Cheese</li>
    </ul>
    <p>Total: $10.0</p>"

> decorated_order.total

=> 10.0

> decorated_order.products

=> ["Bacon", "Cheese"]
# original
order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" )
decorated_order = SalesOrderDecorator.new(order)

# new
class SalesOrderDecorator < SimpleDelegator
  def initialize(*args)
    if args.first.is_a?(SalesOrder)
      super(args.first)
    else
      order = SalesOrder.new(*args)
      super(order)
    end
  end
  ...
end

decorated_order = SalesOrderDecorator.new(["Bacon", "Cheese"], 10.0,
"John Doe" )
decorated_order.html_receipt
Decorator/Presenter
Strategy

       Factory

Adapter (Proxy, Bridge)

Chain of Responsibility

        State

 Primitive Obsession

      Null Object

Decorator (Presenter)
+55 11 3729 14 22
                              www.codeminer42.com.br
                              contact@codeminer42.com.br




slideshare.net/akitaonrails
MUITO OBRIGADO
                              +55 11 3729 14 22
                              www.codeminer42.com.br
                              contact@codeminer42.com.br




slideshare.net/akitaonrails

More Related Content

What's hot

What lies beneath the beautiful code?
What lies beneath the beautiful code?What lies beneath the beautiful code?
What lies beneath the beautiful code?Niranjan Sarade
 
From Ruby to Scala
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scalatod esking
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with JasmineLeon van der Grient
 
Invokedynamic / JSR-292
Invokedynamic / JSR-292Invokedynamic / JSR-292
Invokedynamic / JSR-292ytoshima
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Webnickmbailey
 
Dart, unicorns and rainbows
Dart, unicorns and rainbowsDart, unicorns and rainbows
Dart, unicorns and rainbowschrisbuckett
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Aaron Gustafson
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteDr Nic Williams
 
JavaScript - Chapter 10 - Strings and Arrays
 JavaScript - Chapter 10 - Strings and Arrays JavaScript - Chapter 10 - Strings and Arrays
JavaScript - Chapter 10 - Strings and ArraysWebStackAcademy
 
Declarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing ExperienceDeclarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing ExperienceAlexander Gladysh
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScriptNone
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserHoward Lewis Ship
 
Building High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 FirestarterBuilding High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 FirestarterMithun T. Dhar
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web appschrisbuckett
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxDr Nic Williams
 

What's hot (20)

What lies beneath the beautiful code?
What lies beneath the beautiful code?What lies beneath the beautiful code?
What lies beneath the beautiful code?
 
DataMapper
DataMapperDataMapper
DataMapper
 
From Ruby to Scala
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scala
 
Jstl 8
Jstl 8Jstl 8
Jstl 8
 
Merb
MerbMerb
Merb
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with Jasmine
 
Invokedynamic / JSR-292
Invokedynamic / JSR-292Invokedynamic / JSR-292
Invokedynamic / JSR-292
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Web
 
Dart, unicorns and rainbows
Dart, unicorns and rainbowsDart, unicorns and rainbows
Dart, unicorns and rainbows
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
JavaScript - Chapter 10 - Strings and Arrays
 JavaScript - Chapter 10 - Strings and Arrays JavaScript - Chapter 10 - Strings and Arrays
JavaScript - Chapter 10 - Strings and Arrays
 
Declarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing ExperienceDeclarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing Experience
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Dispatch in Clojure
Dispatch in ClojureDispatch in Clojure
Dispatch in Clojure
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Building High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 FirestarterBuilding High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 Firestarter
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web apps
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 

Similar to Genius is the gold in the mine

All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the TrenchesXavier Noria
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2rubyMarc Chung
 
Apache Spark for Library Developers with William Benton and Erik Erlandson
 Apache Spark for Library Developers with William Benton and Erik Erlandson Apache Spark for Library Developers with William Benton and Erik Erlandson
Apache Spark for Library Developers with William Benton and Erik ErlandsonDatabricks
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amfrailsconf
 
Rails 3.1 Asset Pipeline
Rails 3.1 Asset PipelineRails 3.1 Asset Pipeline
Rails 3.1 Asset PipelineJames Daniels
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introductionTse-Ching Ho
 
Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Karel Minarik
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developergicappa
 
jQuery and Ruby Web Frameworks
jQuery and Ruby Web FrameworksjQuery and Ruby Web Frameworks
jQuery and Ruby Web FrameworksYehuda Katz
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonFokke Zandbergen
 
Advanced Technology for Web Application Design
Advanced Technology for Web Application DesignAdvanced Technology for Web Application Design
Advanced Technology for Web Application DesignBryce Kerley
 

Similar to Genius is the gold in the mine (20)

All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the Trenches
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Scala active record
Scala active recordScala active record
Scala active record
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Apache Spark for Library Developers with William Benton and Erik Erlandson
 Apache Spark for Library Developers with William Benton and Erik Erlandson Apache Spark for Library Developers with William Benton and Erik Erlandson
Apache Spark for Library Developers with William Benton and Erik Erlandson
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Rails 3.1 Asset Pipeline
Rails 3.1 Asset PipelineRails 3.1 Asset Pipeline
Rails 3.1 Asset Pipeline
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developer
 
jQuery and Ruby Web Frameworks
jQuery and Ruby Web FrameworksjQuery and Ruby Web Frameworks
jQuery and Ruby Web Frameworks
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
 
Advanced Technology for Web Application Design
Advanced Technology for Web Application DesignAdvanced Technology for Web Application Design
Advanced Technology for Web Application Design
 
Rack
RackRack
Rack
 

More from Fabio Akita

Devconf 2019 - São Carlos
Devconf 2019 - São CarlosDevconf 2019 - São Carlos
Devconf 2019 - São CarlosFabio Akita
 
Meetup Nerdzão - English Talk about Languages
Meetup Nerdzão  - English Talk about LanguagesMeetup Nerdzão  - English Talk about Languages
Meetup Nerdzão - English Talk about LanguagesFabio Akita
 
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Fabio Akita
 
Desmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPDesmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPFabio Akita
 
Desmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaDesmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaFabio Akita
 
Blockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersBlockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersFabio Akita
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG CampinasFabio Akita
 
Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Fabio Akita
 
30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to RubyFabio Akita
 
Uma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIUma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIFabio Akita
 
THE CONF - Opening Keynote
THE CONF - Opening KeynoteTHE CONF - Opening Keynote
THE CONF - Opening KeynoteFabio Akita
 
A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017Fabio Akita
 
Desmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APDesmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APFabio Akita
 
A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017Fabio Akita
 
A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017Fabio Akita
 
A Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayA Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayFabio Akita
 
A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016Fabio Akita
 
Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Fabio Akita
 
Conexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraConexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraFabio Akita
 
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilThe Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilFabio Akita
 

More from Fabio Akita (20)

Devconf 2019 - São Carlos
Devconf 2019 - São CarlosDevconf 2019 - São Carlos
Devconf 2019 - São Carlos
 
Meetup Nerdzão - English Talk about Languages
Meetup Nerdzão  - English Talk about LanguagesMeetup Nerdzão  - English Talk about Languages
Meetup Nerdzão - English Talk about Languages
 
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
 
Desmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPDesmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SP
 
Desmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaDesmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter Goiania
 
Blockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersBlockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7Masters
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
 
Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017
 
30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby
 
Uma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIUma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TI
 
THE CONF - Opening Keynote
THE CONF - Opening KeynoteTHE CONF - Opening Keynote
THE CONF - Opening Keynote
 
A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017
 
Desmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APDesmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - AP
 
A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017
 
A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017
 
A Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayA Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech Day
 
A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016
 
Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016
 
Conexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraConexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização Prematura
 
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilThe Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
 

Recently uploaded

Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 

Recently uploaded (20)

Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 

Genius is the gold in the mine

  • 1. “ Genius is the gold in the mine; talent is the miner who works and brings it out. ” Lady Marguerite Blessington Donets Basin Mina de carvão-Ucrânia
  • 2.
  • 3. @akitaonrails Ruby e Ruby on Rails - 2006 Rails Summit Latin America - 2008 RubyConf Brasil - 2010
  • 4.
  • 5.
  • 6.
  • 7. Patterns e Anti-Patterns em Ruby Fabio Akita (@akitaonrails)
  • 8.
  • 9. Pattern PADRÃO
  • 10. STANDARD Pattern PADRÃO Default
  • 12.
  • 13.
  • 16. "...each pattern represents our current best guess ... to solve the problem presented. ..., the patterns are still hypotheses, all ... of them -and are therefore all tentative, all free to evolve under the impact of new experience and observation" —Christopher Alexander, A Pattern Language, p. xv
  • 17. require 'erubis' def render_erb(filepath) content = File.read(filepath) template = Erubis::Eruby.new(content) context = { title: "Hello World", paragraph: "This is an ERB template." } output = template.evaluate(context) end puts render_erb("sample.erb") ERB
  • 18. <html> <head><title><%= @title %></title></head> <body> <p><%= @paragraph %></p> </body> </html> <html> <head><title>Hello World</title></head> <body> <p>This is an ERB template.</p> </body> </html> ERB
  • 19. require 'rdiscount' def render_markdown(filepath) content = File.read(filepath) template = RDiscount.new(content) output = template.to_html end puts render_markdown("sample.md") Markdown
  • 20. # Hello World This is a Markdown example * [Markdown](http://daringfireball.net/projects/markdown/ syntax/) <h1>Hello World</h1> <p>This is a Markdown example</p> <ul> <li><a href="http://daringfireball.net/projects/markdown/ syntax/">Markdown</a></li> </ul> Markdown
  • 21. def render(filepath) case filepath when /erb$/ then render_erb(filepath) when /md$/ then render_markdown(filepath) when /sass$/ then render_sass(filepath) ... end end puts render("sample.erb")
  • 23.
  • 24. ENGINE FILE EXTENSIONS REQUIRED LIBRARIES -------------------------- ----------------------- ---------------------------- ERB .erb, .rhtml none (included ruby stdlib) Interpolated String .str none (included ruby core) Erubis .erb, .rhtml, .erubis erubis Haml .haml haml Sass .sass haml (< 3.1) or sass (>= 3.1) Scss .scss haml (< 3.1) or sass (>= 3.1) Less CSS .less less Builder .builder builder Liquid .liquid liquid RDiscount .markdown, .mkd, .md rdiscount Redcarpet .markdown, .mkd, .md redcarpet BlueCloth .markdown, .mkd, .md bluecloth Kramdown .markdown, .mkd, .md kramdown Maruku .markdown, .mkd, .md maruku RedCloth .textile redcloth RDoc .rdoc rdoc Radius .radius radius Markaby .mab markaby Nokogiri .nokogiri nokogiri CoffeeScript .coffee coffee-script (+ javascript) Creole (Wiki markup) .wiki, .creole creole WikiCloth (Wiki markup) .wiki, .mediawiki, .mw wikicloth Yajl .yajl yajl-ruby Template Engines supported by Tilt
  • 25. require 'tilt' template = Tilt.new("sample.erb") context = { title: "Hello World", paragraph: "This is an ERB template." } output = template.render(context) puts output template = Tilt.new("sample.md") output = template.render puts output ERB and Markdown through Tilt
  • 26. require 'tilt' template = Tilt::ErubisTemplate.new("sample.erb") context = { title: "Hello World", paragraph: "This is an ERB template." } output = template.render(context) puts output template = Tilt::RDiscountTemplate.new("sample.md") output = template.render puts output Same example as previously
  • 27. module Tilt ... @preferred_mappings = Hash.new @template_mappings = Hash.new { |h, k| h[k] = [] } # Hash of template path pattern => template implementation class mappings. def self.mappings @template_mappings end ... # Register a template implementation by file extension. def self.register(template_class, *extensions) if template_class.respond_to?(:to_str) # Support register(ext, template_class) too extensions, template_class = [template_class], extensions[0] end extensions.each do |ext| ext = normalize(ext) mappings[ext].unshift(template_class).uniq! end end ... tilt.rb
  • 28. require 'tilt/string' register StringTemplate, 'str' require 'tilt/erb' register ERBTemplate, 'erb', 'rhtml' register ErubisTemplate, 'erb', 'rhtml', 'erubis' require 'tilt/haml' register HamlTemplate, 'haml' require 'tilt/css' register SassTemplate, 'sass' register ScssTemplate, 'scss' register LessTemplate, 'less' ... Tilt#register
  • 29. > Tilt["erb"] => Tilt::ErubisTemplate > Tilt["md"] => Tilt::RDiscountTemplate > Tilt["haml"] => Tilt::HamlTemplate > Tilt['coffee'] => Tilt::CoffeeScriptTemplate Tilt#[]
  • 30. module Tilt ... # Create a new template for the given # file using the file's extension # to determine the the template mapping. def self.new(file, line=nil, options={}, &block) if template_class = self[file] template_class.new(file, line, options, &block) else fail "No template engine registered for #{File.basename(file)}" end end Tilt overrided #new
  • 32. module Tilt # Base class for template implementations. # Subclasses must implement the #prepare method and one # of the #evaluate or #precompiled_template methods. class Template ... def render(scope=Object.new, locals={}, &block) evaluate scope, locals || {}, &block end protected def prepare; ... end def evaluate(scope, locals, &block); ... end def precompiled(locals); ... end def precompiled_template(locals); ... end def precompiled_preamble(locals); ... end def precompiled_postamble(locals); ''; end def compiled_method(locals_keys); ... end end end Tilt::Template Lint
  • 33. module Tilt # RedCloth implementation. See: # http://redcloth.org/ class RedClothTemplate < Template def self.engine_initialized? defined? ::RedCloth end def initialize_engine require_template_library 'redcloth' end def prepare @engine = RedCloth.new(data) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end end end Tilt::RedClothTemplate Implementation
  • 35. Rails Mongrel Sinatra CGI Thin Ramaze Webrick Simple Web
  • 36. Rails Mongrel Sinatra CGI Thin Ramaze Webrick Simple Web
  • 37. Rails Mongrel Sinatra Rack CGI Thin Ramaze Webrick Simple Web
  • 38. class HelloWorld def call(env) [200, {"Content-Type" => "text/plain"}, ["Hello world!"]] end end hello_world = ->(env) { [200, {"Content-Type" => "text/plain"}, ["Hello world!"]] } Minimal Rack Compliant
  • 39. hello_world = ->(env) { [200, {"Content-Type" => "text/html"}, ["<h1>Hello world!</h1>"]] } use Rack::ContentType, "text/html" use Rack::ShowExceptions use Rack::Auth::Basic, "Rack Demo" do |username, password| 'secret' == password end # Setup Rack run Rack::URLMap.new( { "/hello" => hello_world, "/" => Rack::File.new( "index.html" ) } ) rackup app.ru
  • 40. module Rack class ContentType include Rack::Utils def initialize(app, content_type = "text/html") @app, @content_type = app, content_type end def call(env) status, headers, body = @app.call(env) headers = Utils::HeaderHash.new(headers) unless STATUS_WITH_NO_ENTITY_BODY.include?(status) headers['Content-Type'] ||= @content_type end [status, headers, body] end end end rackup app.ru
  • 41. use ActionDispatch::Static use Rack::Lock ... use Rack::Runtime use Rack::MethodOverride use ActionDispatch::RequestId use Rails::Rack::Logger use ActionDispatch::ShowExceptions use ActionDispatch::DebugExceptions use ActionDispatch::RemoteIp use ActionDispatch::Reloader use ActionDispatch::Callbacks use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore use ActionDispatch::Flash use ActionDispatch::ParamsParser use ActionDispatch::Head use Rack::ConditionalGet use Rack::ETag use ActionDispatch::BestStandardsSupport use Warden::Manager use OmniAuth::Strategies::Twitter use OmniAuth::Strategies::Facebook run Rubyconf2012::Application.routes rake middleware (Rails)
  • 43. class Relationship attr_accessor :state def initialize @state = :dating end def get_married make_vows @state = :married eat_wedding_cake end def get_divorced @state = :divorced end def make_vows; "I do"; end def eat_wedding_cake; "Yummy"; end end
  • 44. class Relationship attr_accessor :state def initialize @state = :dating end def get_married raise "Must date before marry" unless @state == :dating make_vows @state = :married eat_wedding_cake end def get_divorced raise "Must be married before divorce" unless @state == :married @state = :divorced end def make_vows; "I do"; end def eat_wedding_cake; "Yummy"; end end
  • 45.
  • 46. class Relationship include AASM aasm do state :dating, initial: true state :married state :divorced event :get_married, :before => :make_vows, :after => :eat_wedding_cake do transitions from: [:dating], to: :married end event :get_divorced do transitions from: [:married], to: :divorced end end def make_vows; "I do"; end def eat_wedding_cake; "Yummy"; end end
  • 47. class Relationship attr_accessor :dating, :married, :divorced def initialize @dating, @married, @divorced = true, false, false end def get_married raise "Must date before marry" unless dating make_vows @dating, @married = false, true eat_wedding_cake end def get_divorced raise "Must be married before divorce" unless married @married, @divorced = false, true end def make_vows; "I do"; end def eat_wedding_cake; "Yummy"; end end
  • 48. State
  • 49. class SaleOrder attr_accessor :items, :value, :checkout_date def initialize(*args) @items, @value, @checkout_date = args end end sale = SaleOrder.new( ['Biscuit', 'Cheese'], 15.0, "2012-07-07")
  • 50. require 'money' require 'time' class SaleOrder attr_reader :value, :checkout_date def initialize(options = {}) @items, @value, @checkout_date = [], Money.new(0.0, "USD"), nil self.items = options[:items] || [] self.value = options[:value] || 0.0 self.checkout_date = options[:checkout_date] end def items=(items); @items += items.dup; end def items(index); @items[index]; end def value=(value); @value = Money.new(value.to_f, "USD"); end def checkout_date=(date) @checkout_date = Date.parse(date) if date end end sale = SaleOrder.new(items: ['Biscuit', 'Cheese'], value: 15.0, checkout_date: "2012-07-07")
  • 52. def slug(title) # 1 if title.nil? title.strip.downcase.tr_s('^[a-z0-9]', '-') end # 2 title.strip.downcase.tr_s('^[a-z0-9]', '-') if title # 3 (title || "").strip.downcase.tr_s('^[a-z0-9]', '-') # 4 title.strip.downcase.tr_s('^[a-z0-9]', '-') rescue nil end http:/ /u.akita.ws/avdi-null
  • 53. class Object def try(*a, &b) if a.empty? && block_given? yield self else public_send(*a, &b) end end end class NilClass def try(*args) nil end end ActiveSupport - Try
  • 54. require 'active_support/core_ext/object/try' def slug(title) title.try(:strip).try(:downcase). try(:tr_s, '^[a-z0-9]', '-') end <%= title ? title.downcase : "" %> <%= title.try(:downcase) %> http:/ /u.akita.ws/avdi-null
  • 55. class NullObject def method_missing(*args, &block) self end def to_a; []; end def to_s; ""; end def to_f; 0.0; end def to_i; 0; end def Maybe(value) value.nil? ? NullObject.new : value def tap; self; end end def to_value; nil; end end class Object def to_value self end end http:/ /u.akita.ws/avdi-null
  • 56. def slug(title) Maybe(title).strip.downcase.tr_s('^[a-z0-9]', '-') end def slug(title) title = Maybe(title) if title.to_value # do something useful end title.strip.downcase.tr_s('^[a-z0-9]', '-') end http:/ /u.akita.ws/avdi-null
  • 57. git clone git://github.com/akitaonrails/null.git cd null gem build null.gemspec gem install null-0.1.gem > require 'null' > Maybe(someobj).foo.bar.something #=> null > (100.0 / (NULL * 15.5) - 150) #=> null object = Maybe(someobj) if object.truthy? # something useful end http:/ /u.akita.ws/avdi-null
  • 59. class SalesOrder < Struct.new(:products, :total, :buyer_name) def html_receipt html_items = products.inject("") do |html, item| html += "<li>#{item}</li>" end html = %{<h1>Thanks for the Purchase #{buyer_name}!</h1> <p>You purchased:</p> <ul> #{html_items} </ul> <p>Total: $#{total}</p>} end end order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" )
  • 60. > order.html_receipt => "<h1>Thanks for the Purchase John Doe!</h1> <p>You purchased:</p> <ul> <li>Bacon</li><li>Cheese</li> </ul> <p>Total: $10.0</p>"
  • 61. class SalesOrder < Struct.new(:products, :total, :buyer_name) def html_receipt html_items = products.inject("") do |html, item| html += "<li>#{item}</li>" end html = %{<h1>Thanks for the Purchase #{buyer_name}!</h1> <p>You purchased:</p> <ul> #{html_items} </ul> <p>Total: $#{total}</p>} end end order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" )
  • 62. class SalesOrder < Struct.new(:products, :total, :buyer_name) end class SalesOrderDecorator < SimpleDelegator def html_receipt html_items = products.inject("") do |html, item| html += "<li>#{item}</li>" end html = %{<h1>Thanks for the Purchase #{buyer_name}!</h1> <p>You purchased:</p> <ul> #{html_items} </ul> <p>Total: $#{total}</p>} end end order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" ) decorated_order = SalesOrderDecorator.new(order)
  • 63. > decorated_order.html_receipt => "<h1>Thanks for the Purchase John Doe!</h1> <p>You purchased:</p> <ul> <li>Bacon</li><li>Cheese</li> </ul> <p>Total: $10.0</p>" > decorated_order.total => 10.0 > decorated_order.products => ["Bacon", "Cheese"]
  • 64. # original order = SalesOrder.new(["Bacon", "Cheese"], 10.0, "John Doe" ) decorated_order = SalesOrderDecorator.new(order) # new class SalesOrderDecorator < SimpleDelegator def initialize(*args) if args.first.is_a?(SalesOrder) super(args.first) else order = SalesOrder.new(*args) super(order) end end ... end decorated_order = SalesOrderDecorator.new(["Bacon", "Cheese"], 10.0, "John Doe" ) decorated_order.html_receipt
  • 66. Strategy Factory Adapter (Proxy, Bridge) Chain of Responsibility State Primitive Obsession Null Object Decorator (Presenter)
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77. +55 11 3729 14 22 www.codeminer42.com.br contact@codeminer42.com.br slideshare.net/akitaonrails
  • 78. MUITO OBRIGADO +55 11 3729 14 22 www.codeminer42.com.br contact@codeminer42.com.br slideshare.net/akitaonrails