SlideShare uma empresa Scribd logo
1 de 70
Baixar para ler offline
Deciphering Rails 3
 with Gregg Pollack
asi
        c        to
                     r         edi
# B        ded        an d R                              _s
     r ovi     er er                                e .to
 # p       end                    pe)       =  typ
         R                     ty
     in                   e =(         e "]
  #
                   t_t
                       yp         Typ
              ten         te nt-
         con      [" Con
    def     d ers
        hea
      end                                   "]
                            ype         ype
                       t_t         t-T
                on ten      on ten
           f c         [" C

                                   source
        de          rs
               ade

                            ng the
            he
          end

              raid of readi
                          ion          ion
                                           "]

        be af
                       at          at
                   loc         Loc
  Don’t     def            ["
                     d ers
                 hea
                                                        rl
               e nd                  (u  rl)        = u
                                 on=          n"]
                            a ti       ca tio
                       loc        "Lo
                 def           s[
                         der

Don’t be afraid of making it your own
                     hea
                   end
                                  us                                                  tus
                                                                                          )
                            s tat                                                 sta
                     def       ta tus                                      co de(
                         @_s                                        at us_
                                                 tu s)       ls .st
                        end                  sta        Uti
                                          =(         ::                                      l]
                                   a tus       R ack                                     [va
                                st          =                                          :
                          def      t a tus                                     ? val
                               @_s                              )        ch)
                                                            val       ea
                             end                    od y =(    to ?(:
                                             ns e_b     po nd_
                                       e spo      . res
Deciphering Rails 3
       Method Compilation

 Microkernel Architecture

alias_method_chain vs super

     ActiveSupport::Concern

    Catch/Throw in Bundler
let’s test t he water
Basics                                def city
                                        return @city
                                      end
class SimplePrint
  attr_accessor :city
                                      def city=(val)
  def initialize(val)                   @city = val
    self.city = val                   end
  end

  def method_missing(meth)
                                   s = SimplePrint.new("moscow")
    puts "#{meth} #{city}"
  end
end
                                    s.toaster


> s = SimplePrint.new("moscow")
 => #<SimplePrint:0x000001020013d0 @city="moscow">
> s.toaster
toaster moscow
 => nil
eval
hash = {'name' => 'Toaster', 'location' => 'Moscow'}

hash.each_pair do |key, value|
  eval <<-RUBY                         @name = 'Toaster'
    @#{key} = value
  RUBY
end
                                       @location = 'Moscow'
puts @name + @location


ToasterMoscow
instan ce_eval
 class Test                                     t = Test.new
   def print                                    t.print
     puts "Hello"                                             Hello
   end
 end
                                                Test.new.instance_eval do
   t = Test.new                                   print
   t.instance_eval do                           end
     def print2
                                                              Hello
       puts "Hello2"
                                                                                                             b6   0>
     end                                                                                              0 0124
                                                                                          t :0   x1
   end                                                                             r# <Tes
                Test.new.print2                                     rin   t   2’ fo
                                                          eth od ‘p
   t.print2                                       d   m
                                     u   nd efine
                                r:
                          dErro
     Hello2        M etho
              No
c lass_eval

   class Test         class Test
   end                end

   class Test         Test.class_eval do
     def print          def print
       puts "Ruby5"       puts "Ruby5"
     end                end
   end                end

   Test.new.print     Test.new.print


   Ruby5              Ruby5
Me thod Com pilation
s = SimplePrint.new [:push_it, :pop_it, :top_it]
                                                         output
s.push_it
s.pop_it                                       => “called push_it”
s.top_it                                       => “called pop_it”
                                               => “called top_it”



class SimplePrint
  attr_accessor :actions

  def initialize(arr)
    self.actions = arr
  end

  def print(meth)
    puts "called #{meth}"
  end

  def method_missing(meth)
    print(meth) if actions.include? meth
  end
end
s = SimplePrint.new [:push_it, :pop_it, :top_it]

30000.times do
  s.push_it
  s.pop_it
  s.top_it
end



     Using Method Missing           5 Seconds
s = SimplePrint.new [:push_it, :pop_it, :top_it]


class SimplePrint                           class BetterPrint
  attr_accessor :actions
                                              def initialize(arr)
  def initialize(arr)                           arr.each do |meth|
    self.actions = arr
  end                                             instance_eval <<-RUBY
                                                    def #{meth}
  def print(meth)                                     print("#{meth}")
    puts "called #{meth}"                           end
  end                                             RUBY


  def method_missing(meth)                      end
    print(meth) if actions.include? meth      end
  end
end                                           def print(meth)
                                                puts "called #{meth}"
                                              end

                                            end
[:push_it, :pop_it, :top_it]

class BetterPrint

  def initialize(arr)         def push_it
    arr.each do |meth|          print("push_it")
                              end
      instance_eval <<-RUBY
        def #{meth}
          print("#{meth}")
        end                    def pop_it
      RUBY                       print("pop_it")
                               end
    end
  end

  def print(meth)             def top_it
    puts "called #{meth}"       print("top_it")
  end                         end

end
s = SimplePrint.new [:push_it, :pop_it, :top_it]

30000.times do
  s.push_it
  s.pop_it
  s.top_it
end



     Using Method Missing             5 Seconds

        Using Instance Eval        3.5 Seconds


                   30 % Faster!
ruby-prof
Using Method Missing




Using Method Compliation
Yehuda’s first commit




rails/actionpack/lib/abstract_controller/metal/mime_responds.rb



      rails/actionpack/lib/abstract_controller/collector.rb
ActiveSupport Callbacks
  Refactored for Speed

  Used in ActionPack, Test::Unit, and ActionController
   before_filter :authenticate

   after_filter :fetch_extra_data

   around_filter :transaction

   skip_filter :admin_only, :except => [:new]




   10x Faster with method compilation
method compliation
    class PostsController < ApplicationController
      layout 'custom'
    end




  layout :symbol

  layout proc{ |c| c.logged_in? ? "member" : "non-member" }

  layout false

  layout nil


  Are	
  you	
  a	
  string,	
  symbol,	
  proc,	
  boolean,	
  or	
  nil?
method compliation
  rails/actionpack/lib/abstract_controller/layouts.rb
 layout_definition = case _layout
   when String
     _layout.inspect
   when Proc
     define_method :_layout_from_proc, &_layout
     "_layout_from_proc(self)"
   when false
     nil
   when true
     raise ArgumentError
   when nil
     name_clause
 end

 self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
   def _layout
      #{layout_definition}
   end
   private :_layout
 RUBY
Me thod Com pilation
let’s test t he water
includin g modules
                      module PrintMeth
                        def print
                          puts "Ruby5"
                        end
                      end


 As Instance Method               As Class Method
  class Test                        class Test
    include PrintMeth                 extend PrintMeth
  end                               end

  Test.new.print                    Test.print

    Ruby5                            Ruby5
nel Arch itecture
M icroker
AbstractController
    A refactor of ActionController in ActionPack
          Provides	
  A	
  Low	
  Level	
  Interface	
  for	
  
          making	
  Customized	
  Controller	
  Base	
  classes.




                     Carl Lerche
Old ActionController Stack    Microkernel Design Pattern


   Cookies                   ActionDispatch
              S
       Routeression
   Layout
          s
             Logger
   MimeRes
            ponds

             s
   Cal lback
            Rendere
                    r
    url_for
              http_
                   auth
   helpers
Old ActionController Stack    Microkernel Design Pattern


   Cookies
   Assigns                    AbstractController
                  Sessio
    Layout
   Callbacks
                          n
           s
   Collector
            Logger
   MimeRes
   Helpers
           ponds
   Layouts
   Logger ks
       ac
   Callb
   Renderinge
           R     nderer
   Translation
     url_for
   ViewPaths
               http_
                    auth
   helpers
Microkernel Design Pattern



  AbstractController
  Assigns
  Callbacks
  Collector
  Helpers
  Layouts
  Logger
  Rendering
  Translation
  ViewPaths
The MicroKernel
   rails/actionpack/lib/abstract_controller/base.rb
    module AbstractController

      class Base
        attr_internal :response_body
        attr_internal :action_name

        abstract!

        # Calls the action going through the entire action dispatch stack.
        def process(action, *args)

        def controller_path

        def action_methods

        private

            def action_method?(name)

            def process_action(method_name, *args)

            def _handle_action_missing

            def method_for_action(action_name)
      end
    end
AbstractController::Base

The microkernel with the bare minimum needed for dispatching

         Assigns
                                    before_filter :authorized
         Callbacks                  after_filter :send_email
         Collector                  around_filter :benchmark
                                    helper :custom
         Helpers                    helper_method :current_user
                                     layout 'custom'
         Layouts                     layout :symbol
         Logger                      layout false
                                     layout nil
         Rendering
         Translation
         ViewPaths

        Modules that can be included to add functionality on top of base
Microkernel Design Pattern


   ActionController::Metal   << AbstractController::Base
                                            Assigns
                                            Base
                                            Callbacks
contains just enough code to get a valid
                                            Collector
   Rack application from a controller
                                            Helpers
                                            Layouts
                                            Logger
                                            Rendering
                                            Translation
                                            ViewPaths


       ActionMailer::Base    << AbstractController::Base
Microkernel Design Pattern

   ActionController::Metal     << AbstractController::Base

app/controllers/hello_controller.rb
 class HelloController < ActionController::Metal
   def index
     self.response_body = "Hello World!"
   end
 end


config/routes.rb
 match 'hello', :to => HelloController.action(:index)
ActionController::Base                           Microkernel Design Pattern

          rails/actionpack/lib/action_controller/metal.rb
     module ActionController
       class Metal < AbstractController::Base
         abstract!

request    def self.call(env)
             action(env['...'][:action]).call(env)
           end

           def self.action(name, klass = ActionDispatch::Request)
             middleware_stack.build do |env|
               new.dispatch(name, klass.new(env))
             end
           end

         def dispatch(name, request)
           @_request = request
           @_env = request.env
           @_env['action_controller.instance'] = self
           process(name)
           response ? response.to_a : [status, headers, response_body]
         end
       end
     end
Cookies
                                 Exceptions
                                 Flash
    ActionController::Metal      Helpers
                                 Redirecting
                                 Rendering
redirect_to post_url(@post)      Responder
                                 UrlFor
class PeopleController < ApplicationController
                                ..... (lots more)
  respond_to :html, :xml, :json

  def index
    @people = Person.find(:all)
                                Assigns
    respond_with(@people)
  end                           Callbacks
end                             Collector
                                Helpers
   AbstractController::Base      Layouts
                                 Logger
                                 Rendering
                                 Translation
                                 ViewPaths
Microkernel Design Pattern
app/controllers/hello_controller.rb
 class HelloController < ActionController::Metal
   include ActionController::Rendering
   append_view_path "#{Rails.root}/app/views"

   def index
     render "hello/index"
   end
 end

app/controllers/hello_controller.rb
class HelloController < ActionController::Metal
  include ActionController::Redirecting
  include Rails.application.routes.url_helpers

  def index
    redirect_to root_url
  end
end
ActionController::Base                        Microkernel Design Pattern

rails/actionpack/lib/action_controller/base.rb
module ActionController
  class Base < Metal
    abstract!

    MODULES = [
      AbstractController::Layouts,
      AbstractController::Translation,
                  module ActionController        Cookies,
      Helpers,                                   Flash,
                    module Helpers
      HideActions,                               Verification,
      UrlFor,                                    RequestForgeryProtection,
                       include AbstractController::Helpers
                                                 Streaming,
      Redirecting,
                       ...                       RecordIdentifier,
      Rendering,
      Renderers::All,                            Instrumentation,
      ConditionalGet,                            AbstractController::Callbacks,
      RackDelegation,                            Rescue
      SessionManagement,                       ]
      Caching,
      MimeResponds,                            MODULES.each do |mod|
      PolymorphicRoutes,                         include mod
      ImplicitRender,                          end
includes
 ActionController::Base
             abstract

                        ActionController Namespace
                                  Cookies
                                  Exceptions
                                  Flash
                                  Helpers
 ActionController::Metal          Redirecting
                                  Rendering
             abstract             Responder
                                  UrlFor
                                  ..... (lots more)



                       AbstractController Namespace
                                  Assigns
                                  Callbacks
                                  Collector
                                  Helpers
AbstractController::Base          Layouts
                                  Logger
            abstract              Rendering
                                  Translation
                                  ViewPaths
nel Arch itecture
M icroker
asi
        c        to
                     r         edi
# B        ded        an d R                              _s
     r ovi     er er                                e .to
 # p       end                    pe)       =  typ
         R                     ty
     in                   e =(         e "]
  #
                   t_t
                       yp         Typ
              ten         te nt-
         con      [" Con
    def     d ers
        hea
      end                                   "]
                            ype         ype
                       t_t         t-T
                on ten      on ten
        de f c      rs [" C
            he ade

          end                              "]
                          ion          ion
                                   source
                       at          at
                   loc         Loc

                           ing the
            def            ["
                       ers

                     f read
                     d
                 hea

             fraid o
                                                        rl
                                         rl)        = u

      t be a
               e nd                  (u       n"]
 Don’                         ti on=      tio
                       loc
                            a          ca
                               s[ "Lo
                 def     der
                     hea
                   end
                                  us                                                  tus
                                                                                          )
                            s tat                                                 sta
                     def       ta tus                                      co de(
                         @_s                                        at us_
                                                 tu s)       ls .st
                        end                  sta        Uti
                                          =(         ::                                      l]
                                   a tus       R ack                                     [va
                                st          =                                          :
                          def      t a tus                                     ? val
                               @_s                              )        ch)
                                                            val       ea
                             end                    od y =(    to ?(:
                                             ns e_b     po nd_
                                       e spo      . res
let’s test t he water
Both instance and class methods
  module PrintMeth                class Test
    def self.included(base)         include PrintMeth
                                  end

            ?
      base.class_eval do
      base.extend(ClassMethods)
        extend ClassMethods
      end                         Test.new.print_podcast
    end                           Test.print_company

    def print_podcast             Ruby5
      puts "Ruby5"                Envy Labs
    end

    module ClassMethods
      def print_company
        puts "Envy Labs"
      end
    end
  end
d_chain vs super
alia s_metho
Can’t modify parent class
 class GenericUser          mr
   def name name_  without_
     "Gregg Pollack"
   end
 end                           module Mr

                                def name_with_mr na
                                                   me
                                  "Mr. " + name_without_mr
                                end
class User < GenericUser
  include Mr                    def self.included(base)
end                                base.class_eval do
                                     alias :name_without_mr :name
puts User.new.name                   alias :name :name_with_mr
                                   end
                                 end
          output
=> “Gregg Pollack”             end



          output wanted
=> “Mr. Gregg Pollack”
Can’t modify parent class
 class GenericUser          mr
   def name name_  without_
     "Gregg Pollack"
   end
 end                           module Mr

                                def name_with_mr na
                                                   me
                                  "Mr. " + name_without_mr
                                end
class User < GenericUser
  include Mr                    def self.included(base)
end                                base.class_eval do
                                     alias :name_without_mr :name
puts User.new.name                   alias :name :name_with_mr
                                   end
                                 end
          output
=> “Gregg Pollack”             end



          output wanted        alias_method_chain :name, :mr
=> “Mr. Gregg Pollack”
class GenericUser
   def name
     "Gregg Pollack"
   end
 end                       module Mr

                             def name
                               "Mr. " + super
class User < GenericUser     end
  include Mr
end                        end




puts User.new.name

          output
=> “Gregg Pollack”



          output wanted
=> “Mr. Gregg Pollack”
AbstractController
    A refactor of ActionController in ActionPack
          Provides	
  A	
  Low	
  Level	
  Interface	
  for	
  
          making	
  Customized	
  Controller	
  Base	
  classes.




                     Carl Lerche
ActionController::Base                        Microkernel Design Pattern

rails/actionpack/lib/action_controller/base.rb
module ActionController
  class Base < Metal
    abstract!

    MODULES = [
      AbstractController::Layouts,
      AbstractController::Translation,
                  module ActionController        Cookies,
      Helpers,                                   Flash,
                    module Helpers
      HideActions,                               Verification,
      UrlFor,                                    RequestForgeryProtection,
                       include AbstractController::Helpers
                                                 Streaming,
      Redirecting,
                       ...                       RecordIdentifier,
      Rendering,
      Renderers::All,                            Instrumentation,
      ConditionalGet,                            AbstractController::Callbacks,
      RackDelegation,                            Rescue
      SessionManagement,                       ]
      Caching,
      MimeResponds,                            MODULES.each do |mod|
      PolymorphicRoutes,                         include mod
      ImplicitRender,                          end
Using Super
rails/actionpack/lib/abstract_controller/helpers.rb
 module AbstractController
   module Helpers
       # Returns a list of modules, normalized from the acceptable kinds of
       # helpers with the following behavior:
       def modules_for_helpers(args)
       ...




rails/actionpack/lib/action_controller/metal/helpers.rb
  module ActionController
                                                     helper :
    module Helpers                                               all
          def modules_for_helpers(args)
            args += all_application_helpers if args.delete(:all)
            super(args)
          end
      ...
thod_chain vs super
a lias_me
upport:: Concern
ActiveS
class MyBar                   module MyCamp
   cattr_accessor :year
                                 def self.included(klass)
   include MyCamp                  klass.class_eval do
                                     self.year = "2010"
   def self.unconference             extend ClassMethods



                                         ?
     puts title + " " + year       end
   end                           end
 end
                                 module ClassMethods
 MyBar.unconference                def title
                                     "BarCamp"
                                   end
BarCamp 2010
                                 end
=> nil
                               end
module MyCamp                module MyCamp
                               extend ActiveSupport::Concern
  def self.included(klass)
    klass.class_eval do        included do
      self.year = "2010"         self.year = "2010"
      extend ClassMethods      end
    end
                               module ClassMethods
  end
                                 def title
                                   "BarCamp"
  module ClassMethods
                                 end
    def title
                               end
      "BarCamp"
                             end
    end
  end
end
When a module with ActiveSupport::Concern
      gets included into a class, it will:


1. Look for ClassMethods and extend them


 module MyCamp
   extend ActiveSupport::Concern
                                   class MyBar
                                     include MyCamp
   module ClassMethods



                }
     def title
                                   end
       "BarCamp"
     end
   end
 end
When a module with ActiveSupport::Concern
      gets included into a class, it will:


2. Look for InstanceMethods and include them


 module MyCamp
   extend ActiveSupport::Concern
                                   class MyBar
                                     include MyCamp
   module InstanceMethods



                }
     def title
                                   end
       "BarCamp"
     end
   end
 end
When a module with ActiveSupport::Concern
      gets included into a class, it will:


3. class_eval everything in the include block


 module MyCamp
   extend ActiveSupport::Concern   class MyBar
                                     include MyCamp



                          }
   included do
     self.year = "2010"            end
   end

 end
4. All included modules get their included hook
run on the base class

module MyFoo
  extend ActiveSupport::Concern




                         }
  included do
    self.planet = "Earth"
  end                                      class MyBar
end
                                             include MyCamp

                                           end
module MyCamp
  extend ActiveSupport::Concern

  include MyFoo
                                  Previously you had to do


                         }
                                     class MyBar
  included do
    self.year = "2010"                 include MyFoo,MyCamp
  end
end                                  end
ActionController::Base                        Microkernel Design Pattern

rails/actionpack/lib/action_controller/base.rb
module ActionController
  class Base < Metal
    abstract!

    MODULES = [
      AbstractController::Layouts,
      AbstractController::Translation,
                  module ActionController        Cookies,
      Helpers,                                   Flash,
                    module Helpers
      HideActions,                               Verification,
      UrlFor,                                    RequestForgeryProtection,
                       include AbstractController::Helpers
                                                 Streaming,
      Redirecting,
                       ...                       RecordIdentifier,
      Rendering,
      Renderers::All,                            Instrumentation,
      ConditionalGet,                            AbstractController::Callbacks,
      RackDelegation,                            Rescue
      SessionManagement,                       ]
      Caching,
      MimeResponds,                            MODULES.each do |mod|
      PolymorphicRoutes,                         include mod
      ImplicitRender,                          end
rails/actionpack/lib/abstract_controller/helpers.rb
  module AbstractController
    module Helpers
      extend ActiveSupport::Concern




                                               }
      included do
        class_attribute :_helpers
        delegate :_helpers, :to => :'self.class'
        self._helpers = Module.new                        ../action_controller/base.rb
      end
                                                            module ActionController
                                                              class Base < Metal
rails/actionpack/lib/action_controller/metal/helpers.rb
                                                              include Helpers
  module ActionController
    module Helpers
      extend ActiveSupport::Concern

      include AbstractController::Helpers




                                      }
      included do
        class_attribute :helpers_path
        self.helpers_path = []
      end
      ...
upport::C oncern
     ActiveS

1. Look for ClassMethods and extend them

2. Look for InstanceMethods and include them

3. class_eval everything in the include block

4. All included modules get their included hook
run on the base class
hrow in B undler
Catch/T
Dependency Resolution
   Depth	
  First	
  Search
                                dependencies

           paperclip                            searchlogic


 shoulda           sqlite3             aws-s3          activerecord
                                                    Conflict

      mocha            rake-compiler
Control Flow


   if	
        method	
  return
   elsif	
     method	
  invocation
   else
   unless
   for         raise	
  ..	
  rescue
   while
   case        catch	
  ..	
  throw
Control Flow
   catch(:marker) do
     puts "This will get executed"
     throw :marker
     puts "This will not get executed"
   end                                   begin
                                           ..
   This will get executed
   => nil                                  raise
                                           ..
   catch(:marker) do                     rescue
     puts "This will get executed"         ..
     throw :marker, "hello"              end
     puts "This will not get executed"
   end

   This will get executed
   => "hello"
Dependency Resolution
   Depth	
  First	
  Search
                                dependencies

           paperclip                            searchlogic


 shoulda           sqlite3             aws-s3          activerecord
                                                    Conflict

      mocha            rake-compiler
Inside Bundler
                     Bundler/lib/bundler/resolver.rb
      when resolving a requirement
   retval = catch(requirement.name) do
     resolve(reqs, activated)
   end


  when activated gem is conflicted to go to initial requirement
  parent = current.required_by.last || existing.required_by.last

  debug { "    -> Jumping to: #{parent.name}" }
  throw parent.name, existing.required_by.last.name


  when gem is not activated, but it’s dependencies conflict
  parent = current.required_by.last || existing.required_by.last

  debug { "    -> Jumping to: #{parent.name}" }
  throw parent.name, existing.required_by.last.name
hrow in B undler
Catch/T
Deciphering Rails 3
       Method Compilation

 Microkernel Architecture

alias_method_chain vs super

     ActiveSupport::Concern

    Catch/Throw in Bundler
asi
        c        to
                     r         edi
# B        ded        an d R                              _s
     r ovi     er er                                e .to
 # p       end                    pe)       =  typ
         R                     ty
     in                   e =(         e "]
  #
                   t_t
                       yp         Typ
              ten         te nt-
         con      [" Con
    def     d ers
        hea
      end                                   "]
                            ype         ype
                       t_t         t-T
                on ten      on ten
           f c         [" C

                                   source
        de          rs
               ade

                            ng the
            he
          end

              raid of readi
                          ion          ion
                                           "]

        be af
                       at          at
                   loc         Loc
  Don’t     def            ["
                     d ers
                 hea
                                                        rl
               e nd                  (u  rl)        = u
                                 on=          n"]
                            a ti       ca tio
                       loc        "Lo
                 def           s[
                         der

Don’t be afraid of making it your own
                     hea
                   end
                                  us                                                  tus
                                                                                          )
                            s tat                                                 sta
                     def       ta tus                                      co de(
                         @_s                                        at us_
                                                 tu s)       ls .st
                        end                  sta        Uti
                                          =(         ::                                      l]
                                   a tus       R ack                                     [va
                                st          =                                          :
                          def      t a tus                                     ? val
                               @_s                              )        ch)
                                                            val       ea
                             end                    od y =(    to ?(:
                                             ns e_b     po nd_
                                       e spo      . res
Creative Commons
           name                     author                               URL
Construction Time Again     v1ctory_1s_m1ne   http://www.flickr.com/photos/v1ctory_1s_m1ne/3416173688/

Microprocesseur             Stéfan            http://www.flickr.com/photos/st3f4n/2389606236/

chain-of-14-cubes.4         Ardonik           http://www.flickr.com/photos/ardonik/3273300715/

(untitled)                  squacco           http://www.flickr.com/photos/squeakywheel/454111821/

up there                    Paul Mayne        http://www.flickr.com/photos/paulm/873641065/

Day 5/365 - Night Terrors   Tom Lin :3=       http://www.flickr.com/photos/tom_lin/3193080175/

Testing the water           The Brit_2        http://www.flickr.com/photos/26686573@N00/2188837324/

High Dive                   Zhao Hua Xi Shi   http://www.flickr.com/photos/elephantonabicycle/4321415975/
http://RailsBest.com
Slides => http://bit.ly/railstoaster




Спасибо
          @GreggPollack
       Gregg@EnvyLabs.com




        http://envylabs.com

Mais conteúdo relacionado

Mais procurados

Python decorators (中文)
Python decorators (中文)Python decorators (中文)
Python decorators (中文)Yiwei Chen
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick referenceArduino Aficionado
 
Array String - Web Programming
Array String - Web ProgrammingArray String - Web Programming
Array String - Web ProgrammingAmirul Azhar
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
 
Ruby, muito mais que reflexivo
Ruby, muito mais que reflexivoRuby, muito mais que reflexivo
Ruby, muito mais que reflexivoFabio Kung
 

Mais procurados (8)

Python decorators (中文)
Python decorators (中文)Python decorators (中文)
Python decorators (中文)
 
A regex ekon16
A regex ekon16A regex ekon16
A regex ekon16
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick reference
 
Array String - Web Programming
Array String - Web ProgrammingArray String - Web Programming
Array String - Web Programming
 
Awk programming
Awk programming Awk programming
Awk programming
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Ruby, muito mais que reflexivo
Ruby, muito mais que reflexivoRuby, muito mais que reflexivo
Ruby, muito mais que reflexivo
 
Arrows in perl
Arrows in perlArrows in perl
Arrows in perl
 

Destaque

CouchDB: A NoSQL database
CouchDB: A NoSQL databaseCouchDB: A NoSQL database
CouchDB: A NoSQL databaseRubyc Slides
 
Your first sinatra app
Your first sinatra appYour first sinatra app
Your first sinatra appRubyc Slides
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmineRubyc Slides
 
Probando las vistas
Probando las vistasProbando las vistas
Probando las vistasRubyc Slides
 
Eurocodes oversigt 2013
Eurocodes oversigt 2013Eurocodes oversigt 2013
Eurocodes oversigt 2013Dansk Standard
 

Destaque (7)

CouchDB: A NoSQL database
CouchDB: A NoSQL databaseCouchDB: A NoSQL database
CouchDB: A NoSQL database
 
Intro to Rack
Intro to RackIntro to Rack
Intro to Rack
 
Your first sinatra app
Your first sinatra appYour first sinatra app
Your first sinatra app
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmine
 
Probando las vistas
Probando las vistasProbando las vistas
Probando las vistas
 
Eurocodes oversigt 2013
Eurocodes oversigt 2013Eurocodes oversigt 2013
Eurocodes oversigt 2013
 
L4 Microkernel :: Design Overview
L4 Microkernel :: Design OverviewL4 Microkernel :: Design Overview
L4 Microkernel :: Design Overview
 

Semelhante a Decyphering Rails 3

Semelhante a Decyphering Rails 3 (20)

Breaking the wall
Breaking the wallBreaking the wall
Breaking the wall
 
Clojure for Rubyists
Clojure for RubyistsClojure for Rubyists
Clojure for Rubyists
 
Unit vii wp ppt
Unit vii wp pptUnit vii wp ppt
Unit vii wp ppt
 
Scripting ppt
Scripting pptScripting ppt
Scripting ppt
 
tutorial7
tutorial7tutorial7
tutorial7
 
tutorial7
tutorial7tutorial7
tutorial7
 
Scripting ppt
Scripting pptScripting ppt
Scripting ppt
 
Crystal presentation in NY
Crystal presentation in NYCrystal presentation in NY
Crystal presentation in NY
 
perl_lessons
perl_lessonsperl_lessons
perl_lessons
 
perl_lessons
perl_lessonsperl_lessons
perl_lessons
 
Class 31: Deanonymizing
Class 31: DeanonymizingClass 31: Deanonymizing
Class 31: Deanonymizing
 
Purely Functional Data Structures ex3.3 leftist heap
Purely Functional Data Structures ex3.3 leftist heapPurely Functional Data Structures ex3.3 leftist heap
Purely Functional Data Structures ex3.3 leftist heap
 
String Manipulation in Python
String Manipulation in PythonString Manipulation in Python
String Manipulation in Python
 
Engr 371 final exam august 1999
Engr 371 final exam august 1999Engr 371 final exam august 1999
Engr 371 final exam august 1999
 
AMIS - Can collections speed up your PL/SQL?
AMIS - Can collections speed up your PL/SQL?AMIS - Can collections speed up your PL/SQL?
AMIS - Can collections speed up your PL/SQL?
 
C language
C languageC language
C language
 
GoでKVSを書けるのか
GoでKVSを書けるのかGoでKVSを書けるのか
GoでKVSを書けるのか
 
drb09
drb09drb09
drb09
 
C language first program
C language first programC language first program
C language first program
 
State Space C-Reductions @ ETAPS Workshop GRAPHITE 2013
State Space C-Reductions @ ETAPS Workshop GRAPHITE 2013State Space C-Reductions @ ETAPS Workshop GRAPHITE 2013
State Space C-Reductions @ ETAPS Workshop GRAPHITE 2013
 

Mais de .toster

Native look and feel bbui & alicejs
Native look and feel bbui & alicejsNative look and feel bbui & alicejs
Native look and feel bbui & alicejs.toster
 
Практики применения JRuby
Практики применения JRubyПрактики применения JRuby
Практики применения JRuby.toster
 
Sinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящееSinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящее.toster
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
Understanding the Rails web model and scalability options
Understanding the Rails web model and scalability optionsUnderstanding the Rails web model and scalability options
Understanding the Rails web model and scalability options.toster
 
Михаил Черномордиков
Михаил ЧерномордиковМихаил Черномордиков
Михаил Черномордиков.toster
 
Андрей Юношев
Андрей Юношев Андрей Юношев
Андрей Юношев .toster
 
Алексей Тарасенко - Zeptolab
Алексей Тарасенко - ZeptolabАлексей Тарасенко - Zeptolab
Алексей Тарасенко - Zeptolab.toster
 
Maximiliano Firtman - Разработка приложений с помощью PhoneGap
Maximiliano Firtman - Разработка приложений с помощью PhoneGap Maximiliano Firtman - Разработка приложений с помощью PhoneGap
Maximiliano Firtman - Разработка приложений с помощью PhoneGap .toster
 
Вадим Башуров
Вадим БашуровВадим Башуров
Вадим Башуров.toster
 
Вадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимонВадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимон.toster
 
Вадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимонВадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимон.toster
 
Pablo Villalba -
Pablo Villalba - Pablo Villalba -
Pablo Villalba - .toster
 
Jordi Romero Api for-the-mobile-era
Jordi Romero Api for-the-mobile-eraJordi Romero Api for-the-mobile-era
Jordi Romero Api for-the-mobile-era.toster
 
Презентация Юрия Ветрова (Mail.ru Group)
Презентация Юрия Ветрова (Mail.ru Group)Презентация Юрия Ветрова (Mail.ru Group)
Презентация Юрия Ветрова (Mail.ru Group).toster
 
Внутренняя архитектура и устройства соц. сети "Одноклассники"
Внутренняя архитектура и устройства соц. сети "Одноклассники"Внутренняя архитектура и устройства соц. сети "Одноклассники"
Внутренняя архитектура и устройства соц. сети "Одноклассники".toster
 
Reusable Code, for good or for awesome!
Reusable Code, for good or for awesome!Reusable Code, for good or for awesome!
Reusable Code, for good or for awesome!.toster
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}.toster
 
Wild wild web. html5 era
Wild wild web. html5 eraWild wild web. html5 era
Wild wild web. html5 era.toster
 
Web matrix
Web matrixWeb matrix
Web matrix.toster
 

Mais de .toster (20)

Native look and feel bbui & alicejs
Native look and feel bbui & alicejsNative look and feel bbui & alicejs
Native look and feel bbui & alicejs
 
Практики применения JRuby
Практики применения JRubyПрактики применения JRuby
Практики применения JRuby
 
Sinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящееSinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящее
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Understanding the Rails web model and scalability options
Understanding the Rails web model and scalability optionsUnderstanding the Rails web model and scalability options
Understanding the Rails web model and scalability options
 
Михаил Черномордиков
Михаил ЧерномордиковМихаил Черномордиков
Михаил Черномордиков
 
Андрей Юношев
Андрей Юношев Андрей Юношев
Андрей Юношев
 
Алексей Тарасенко - Zeptolab
Алексей Тарасенко - ZeptolabАлексей Тарасенко - Zeptolab
Алексей Тарасенко - Zeptolab
 
Maximiliano Firtman - Разработка приложений с помощью PhoneGap
Maximiliano Firtman - Разработка приложений с помощью PhoneGap Maximiliano Firtman - Разработка приложений с помощью PhoneGap
Maximiliano Firtman - Разработка приложений с помощью PhoneGap
 
Вадим Башуров
Вадим БашуровВадим Башуров
Вадим Башуров
 
Вадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимонВадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимон
 
Вадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимонВадим Башуров - Как откусить от яблока лимон
Вадим Башуров - Как откусить от яблока лимон
 
Pablo Villalba -
Pablo Villalba - Pablo Villalba -
Pablo Villalba -
 
Jordi Romero Api for-the-mobile-era
Jordi Romero Api for-the-mobile-eraJordi Romero Api for-the-mobile-era
Jordi Romero Api for-the-mobile-era
 
Презентация Юрия Ветрова (Mail.ru Group)
Презентация Юрия Ветрова (Mail.ru Group)Презентация Юрия Ветрова (Mail.ru Group)
Презентация Юрия Ветрова (Mail.ru Group)
 
Внутренняя архитектура и устройства соц. сети "Одноклассники"
Внутренняя архитектура и устройства соц. сети "Одноклассники"Внутренняя архитектура и устройства соц. сети "Одноклассники"
Внутренняя архитектура и устройства соц. сети "Одноклассники"
 
Reusable Code, for good or for awesome!
Reusable Code, for good or for awesome!Reusable Code, for good or for awesome!
Reusable Code, for good or for awesome!
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
 
Wild wild web. html5 era
Wild wild web. html5 eraWild wild web. html5 era
Wild wild web. html5 era
 
Web matrix
Web matrixWeb matrix
Web matrix
 

Último

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
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 

Último (20)

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
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 

Decyphering Rails 3

  • 1. Deciphering Rails 3 with Gregg Pollack
  • 2. asi c to r edi # B ded an d R _s r ovi er er e .to # p end pe) = typ R ty in e =( e "] # t_t yp Typ ten te nt- con [" Con def d ers hea end "] ype ype t_t t-T on ten on ten f c [" C source de rs ade ng the he end raid of readi ion ion "] be af at at loc Loc Don’t def [" d ers hea rl e nd (u rl) = u on= n"] a ti ca tio loc "Lo def s[ der Don’t be afraid of making it your own hea end us tus ) s tat sta def ta tus co de( @_s at us_ tu s) ls .st end sta Uti =( :: l] a tus R ack [va st = : def t a tus ? val @_s ) ch) val ea end od y =( to ?(: ns e_b po nd_ e spo . res
  • 3. Deciphering Rails 3 Method Compilation Microkernel Architecture alias_method_chain vs super ActiveSupport::Concern Catch/Throw in Bundler
  • 4. let’s test t he water
  • 5. Basics def city return @city end class SimplePrint attr_accessor :city def city=(val) def initialize(val) @city = val self.city = val end end def method_missing(meth) s = SimplePrint.new("moscow") puts "#{meth} #{city}" end end s.toaster > s = SimplePrint.new("moscow") => #<SimplePrint:0x000001020013d0 @city="moscow"> > s.toaster toaster moscow => nil
  • 6. eval hash = {'name' => 'Toaster', 'location' => 'Moscow'} hash.each_pair do |key, value| eval <<-RUBY @name = 'Toaster' @#{key} = value RUBY end @location = 'Moscow' puts @name + @location ToasterMoscow
  • 7. instan ce_eval class Test t = Test.new def print t.print puts "Hello" Hello end end Test.new.instance_eval do t = Test.new print t.instance_eval do end def print2 Hello puts "Hello2" b6 0> end 0 0124 t :0 x1 end r# <Tes Test.new.print2 rin t 2’ fo eth od ‘p t.print2 d m u nd efine r: dErro Hello2 M etho No
  • 8. c lass_eval class Test class Test end end class Test Test.class_eval do def print def print puts "Ruby5" puts "Ruby5" end end end end Test.new.print Test.new.print Ruby5 Ruby5
  • 9. Me thod Com pilation
  • 10. s = SimplePrint.new [:push_it, :pop_it, :top_it] output s.push_it s.pop_it => “called push_it” s.top_it => “called pop_it” => “called top_it” class SimplePrint attr_accessor :actions def initialize(arr) self.actions = arr end def print(meth) puts "called #{meth}" end def method_missing(meth) print(meth) if actions.include? meth end end
  • 11. s = SimplePrint.new [:push_it, :pop_it, :top_it] 30000.times do s.push_it s.pop_it s.top_it end Using Method Missing 5 Seconds
  • 12. s = SimplePrint.new [:push_it, :pop_it, :top_it] class SimplePrint class BetterPrint attr_accessor :actions def initialize(arr) def initialize(arr) arr.each do |meth| self.actions = arr end instance_eval <<-RUBY def #{meth} def print(meth) print("#{meth}") puts "called #{meth}" end end RUBY def method_missing(meth) end print(meth) if actions.include? meth end end end def print(meth) puts "called #{meth}" end end
  • 13. [:push_it, :pop_it, :top_it] class BetterPrint def initialize(arr) def push_it arr.each do |meth| print("push_it") end instance_eval <<-RUBY def #{meth} print("#{meth}") end def pop_it RUBY print("pop_it") end end end def print(meth) def top_it puts "called #{meth}" print("top_it") end end end
  • 14. s = SimplePrint.new [:push_it, :pop_it, :top_it] 30000.times do s.push_it s.pop_it s.top_it end Using Method Missing 5 Seconds Using Instance Eval 3.5 Seconds 30 % Faster!
  • 17. ActiveSupport Callbacks Refactored for Speed Used in ActionPack, Test::Unit, and ActionController before_filter :authenticate after_filter :fetch_extra_data around_filter :transaction skip_filter :admin_only, :except => [:new] 10x Faster with method compilation
  • 18. method compliation class PostsController < ApplicationController layout 'custom' end layout :symbol layout proc{ |c| c.logged_in? ? "member" : "non-member" } layout false layout nil Are  you  a  string,  symbol,  proc,  boolean,  or  nil?
  • 19. method compliation rails/actionpack/lib/abstract_controller/layouts.rb layout_definition = case _layout when String _layout.inspect when Proc define_method :_layout_from_proc, &_layout "_layout_from_proc(self)" when false nil when true raise ArgumentError when nil name_clause end self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout #{layout_definition} end private :_layout RUBY
  • 20. Me thod Com pilation
  • 21. let’s test t he water
  • 22. includin g modules module PrintMeth def print puts "Ruby5" end end As Instance Method As Class Method class Test class Test include PrintMeth extend PrintMeth end end Test.new.print Test.print Ruby5 Ruby5
  • 24. AbstractController A refactor of ActionController in ActionPack Provides  A  Low  Level  Interface  for   making  Customized  Controller  Base  classes. Carl Lerche
  • 25. Old ActionController Stack Microkernel Design Pattern Cookies ActionDispatch S Routeression Layout s Logger MimeRes ponds s Cal lback Rendere r url_for http_ auth helpers
  • 26. Old ActionController Stack Microkernel Design Pattern Cookies Assigns AbstractController Sessio Layout Callbacks n s Collector Logger MimeRes Helpers ponds Layouts Logger ks ac Callb Renderinge R nderer Translation url_for ViewPaths http_ auth helpers
  • 27. Microkernel Design Pattern AbstractController Assigns Callbacks Collector Helpers Layouts Logger Rendering Translation ViewPaths
  • 28. The MicroKernel rails/actionpack/lib/abstract_controller/base.rb module AbstractController class Base attr_internal :response_body attr_internal :action_name abstract! # Calls the action going through the entire action dispatch stack. def process(action, *args) def controller_path def action_methods private def action_method?(name) def process_action(method_name, *args) def _handle_action_missing def method_for_action(action_name) end end
  • 29. AbstractController::Base The microkernel with the bare minimum needed for dispatching Assigns before_filter :authorized Callbacks after_filter :send_email Collector around_filter :benchmark helper :custom Helpers helper_method :current_user layout 'custom' Layouts layout :symbol Logger layout false layout nil Rendering Translation ViewPaths Modules that can be included to add functionality on top of base
  • 30. Microkernel Design Pattern ActionController::Metal << AbstractController::Base Assigns Base Callbacks contains just enough code to get a valid Collector Rack application from a controller Helpers Layouts Logger Rendering Translation ViewPaths ActionMailer::Base << AbstractController::Base
  • 31. Microkernel Design Pattern ActionController::Metal << AbstractController::Base app/controllers/hello_controller.rb class HelloController < ActionController::Metal def index self.response_body = "Hello World!" end end config/routes.rb match 'hello', :to => HelloController.action(:index)
  • 32. ActionController::Base Microkernel Design Pattern rails/actionpack/lib/action_controller/metal.rb module ActionController class Metal < AbstractController::Base abstract! request def self.call(env) action(env['...'][:action]).call(env) end def self.action(name, klass = ActionDispatch::Request) middleware_stack.build do |env| new.dispatch(name, klass.new(env)) end end def dispatch(name, request) @_request = request @_env = request.env @_env['action_controller.instance'] = self process(name) response ? response.to_a : [status, headers, response_body] end end end
  • 33. Cookies Exceptions Flash ActionController::Metal Helpers Redirecting Rendering redirect_to post_url(@post) Responder UrlFor class PeopleController < ApplicationController ..... (lots more) respond_to :html, :xml, :json def index @people = Person.find(:all) Assigns respond_with(@people) end Callbacks end Collector Helpers AbstractController::Base Layouts Logger Rendering Translation ViewPaths
  • 34. Microkernel Design Pattern app/controllers/hello_controller.rb class HelloController < ActionController::Metal include ActionController::Rendering append_view_path "#{Rails.root}/app/views" def index render "hello/index" end end app/controllers/hello_controller.rb class HelloController < ActionController::Metal include ActionController::Redirecting include Rails.application.routes.url_helpers def index redirect_to root_url end end
  • 35. ActionController::Base Microkernel Design Pattern rails/actionpack/lib/action_controller/base.rb module ActionController class Base < Metal abstract! MODULES = [ AbstractController::Layouts, AbstractController::Translation, module ActionController Cookies, Helpers, Flash, module Helpers HideActions, Verification, UrlFor, RequestForgeryProtection, include AbstractController::Helpers Streaming, Redirecting, ... RecordIdentifier, Rendering, Renderers::All, Instrumentation, ConditionalGet, AbstractController::Callbacks, RackDelegation, Rescue SessionManagement, ] Caching, MimeResponds, MODULES.each do |mod| PolymorphicRoutes, include mod ImplicitRender, end
  • 36. includes ActionController::Base abstract ActionController Namespace Cookies Exceptions Flash Helpers ActionController::Metal Redirecting Rendering abstract Responder UrlFor ..... (lots more) AbstractController Namespace Assigns Callbacks Collector Helpers AbstractController::Base Layouts Logger abstract Rendering Translation ViewPaths
  • 38. asi c to r edi # B ded an d R _s r ovi er er e .to # p end pe) = typ R ty in e =( e "] # t_t yp Typ ten te nt- con [" Con def d ers hea end "] ype ype t_t t-T on ten on ten de f c rs [" C he ade end "] ion ion source at at loc Loc ing the def [" ers f read d hea fraid o rl rl) = u t be a e nd (u n"] Don’ ti on= tio loc a ca s[ "Lo def der hea end us tus ) s tat sta def ta tus co de( @_s at us_ tu s) ls .st end sta Uti =( :: l] a tus R ack [va st = : def t a tus ? val @_s ) ch) val ea end od y =( to ?(: ns e_b po nd_ e spo . res
  • 39. let’s test t he water
  • 40. Both instance and class methods module PrintMeth class Test def self.included(base) include PrintMeth end ? base.class_eval do base.extend(ClassMethods) extend ClassMethods end Test.new.print_podcast end Test.print_company def print_podcast Ruby5 puts "Ruby5" Envy Labs end module ClassMethods def print_company puts "Envy Labs" end end end
  • 42. Can’t modify parent class class GenericUser mr def name name_ without_ "Gregg Pollack" end end module Mr def name_with_mr na me "Mr. " + name_without_mr end class User < GenericUser include Mr def self.included(base) end base.class_eval do alias :name_without_mr :name puts User.new.name alias :name :name_with_mr end end output => “Gregg Pollack” end output wanted => “Mr. Gregg Pollack”
  • 43. Can’t modify parent class class GenericUser mr def name name_ without_ "Gregg Pollack" end end module Mr def name_with_mr na me "Mr. " + name_without_mr end class User < GenericUser include Mr def self.included(base) end base.class_eval do alias :name_without_mr :name puts User.new.name alias :name :name_with_mr end end output => “Gregg Pollack” end output wanted alias_method_chain :name, :mr => “Mr. Gregg Pollack”
  • 44. class GenericUser def name "Gregg Pollack" end end module Mr def name "Mr. " + super class User < GenericUser end include Mr end end puts User.new.name output => “Gregg Pollack” output wanted => “Mr. Gregg Pollack”
  • 45. AbstractController A refactor of ActionController in ActionPack Provides  A  Low  Level  Interface  for   making  Customized  Controller  Base  classes. Carl Lerche
  • 46. ActionController::Base Microkernel Design Pattern rails/actionpack/lib/action_controller/base.rb module ActionController class Base < Metal abstract! MODULES = [ AbstractController::Layouts, AbstractController::Translation, module ActionController Cookies, Helpers, Flash, module Helpers HideActions, Verification, UrlFor, RequestForgeryProtection, include AbstractController::Helpers Streaming, Redirecting, ... RecordIdentifier, Rendering, Renderers::All, Instrumentation, ConditionalGet, AbstractController::Callbacks, RackDelegation, Rescue SessionManagement, ] Caching, MimeResponds, MODULES.each do |mod| PolymorphicRoutes, include mod ImplicitRender, end
  • 47. Using Super rails/actionpack/lib/abstract_controller/helpers.rb module AbstractController module Helpers # Returns a list of modules, normalized from the acceptable kinds of # helpers with the following behavior: def modules_for_helpers(args) ... rails/actionpack/lib/action_controller/metal/helpers.rb module ActionController helper : module Helpers all def modules_for_helpers(args) args += all_application_helpers if args.delete(:all) super(args) end ...
  • 50. class MyBar module MyCamp cattr_accessor :year def self.included(klass) include MyCamp klass.class_eval do self.year = "2010" def self.unconference extend ClassMethods ? puts title + " " + year end end end end module ClassMethods MyBar.unconference def title "BarCamp" end BarCamp 2010 end => nil end
  • 51. module MyCamp module MyCamp extend ActiveSupport::Concern def self.included(klass) klass.class_eval do included do self.year = "2010" self.year = "2010" extend ClassMethods end end module ClassMethods end def title "BarCamp" module ClassMethods end def title end "BarCamp" end end end end
  • 52. When a module with ActiveSupport::Concern gets included into a class, it will: 1. Look for ClassMethods and extend them module MyCamp extend ActiveSupport::Concern class MyBar include MyCamp module ClassMethods } def title end "BarCamp" end end end
  • 53. When a module with ActiveSupport::Concern gets included into a class, it will: 2. Look for InstanceMethods and include them module MyCamp extend ActiveSupport::Concern class MyBar include MyCamp module InstanceMethods } def title end "BarCamp" end end end
  • 54. When a module with ActiveSupport::Concern gets included into a class, it will: 3. class_eval everything in the include block module MyCamp extend ActiveSupport::Concern class MyBar include MyCamp } included do self.year = "2010" end end end
  • 55. 4. All included modules get their included hook run on the base class module MyFoo extend ActiveSupport::Concern } included do self.planet = "Earth" end class MyBar end include MyCamp end module MyCamp extend ActiveSupport::Concern include MyFoo Previously you had to do } class MyBar included do self.year = "2010" include MyFoo,MyCamp end end end
  • 56. ActionController::Base Microkernel Design Pattern rails/actionpack/lib/action_controller/base.rb module ActionController class Base < Metal abstract! MODULES = [ AbstractController::Layouts, AbstractController::Translation, module ActionController Cookies, Helpers, Flash, module Helpers HideActions, Verification, UrlFor, RequestForgeryProtection, include AbstractController::Helpers Streaming, Redirecting, ... RecordIdentifier, Rendering, Renderers::All, Instrumentation, ConditionalGet, AbstractController::Callbacks, RackDelegation, Rescue SessionManagement, ] Caching, MimeResponds, MODULES.each do |mod| PolymorphicRoutes, include mod ImplicitRender, end
  • 57. rails/actionpack/lib/abstract_controller/helpers.rb module AbstractController module Helpers extend ActiveSupport::Concern } included do class_attribute :_helpers delegate :_helpers, :to => :'self.class' self._helpers = Module.new ../action_controller/base.rb end module ActionController class Base < Metal rails/actionpack/lib/action_controller/metal/helpers.rb include Helpers module ActionController module Helpers extend ActiveSupport::Concern include AbstractController::Helpers } included do class_attribute :helpers_path self.helpers_path = [] end ...
  • 58. upport::C oncern ActiveS 1. Look for ClassMethods and extend them 2. Look for InstanceMethods and include them 3. class_eval everything in the include block 4. All included modules get their included hook run on the base class
  • 59. hrow in B undler Catch/T
  • 60. Dependency Resolution Depth  First  Search dependencies paperclip searchlogic shoulda sqlite3 aws-s3 activerecord Conflict mocha rake-compiler
  • 61. Control Flow if   method  return elsif   method  invocation else unless for raise  ..  rescue while case catch  ..  throw
  • 62. Control Flow catch(:marker) do puts "This will get executed" throw :marker puts "This will not get executed" end begin .. This will get executed => nil raise .. catch(:marker) do rescue puts "This will get executed" .. throw :marker, "hello" end puts "This will not get executed" end This will get executed => "hello"
  • 63. Dependency Resolution Depth  First  Search dependencies paperclip searchlogic shoulda sqlite3 aws-s3 activerecord Conflict mocha rake-compiler
  • 64. Inside Bundler Bundler/lib/bundler/resolver.rb when resolving a requirement retval = catch(requirement.name) do resolve(reqs, activated) end when activated gem is conflicted to go to initial requirement parent = current.required_by.last || existing.required_by.last debug { " -> Jumping to: #{parent.name}" } throw parent.name, existing.required_by.last.name when gem is not activated, but it’s dependencies conflict parent = current.required_by.last || existing.required_by.last debug { " -> Jumping to: #{parent.name}" } throw parent.name, existing.required_by.last.name
  • 65. hrow in B undler Catch/T
  • 66. Deciphering Rails 3 Method Compilation Microkernel Architecture alias_method_chain vs super ActiveSupport::Concern Catch/Throw in Bundler
  • 67. asi c to r edi # B ded an d R _s r ovi er er e .to # p end pe) = typ R ty in e =( e "] # t_t yp Typ ten te nt- con [" Con def d ers hea end "] ype ype t_t t-T on ten on ten f c [" C source de rs ade ng the he end raid of readi ion ion "] be af at at loc Loc Don’t def [" d ers hea rl e nd (u rl) = u on= n"] a ti ca tio loc "Lo def s[ der Don’t be afraid of making it your own hea end us tus ) s tat sta def ta tus co de( @_s at us_ tu s) ls .st end sta Uti =( :: l] a tus R ack [va st = : def t a tus ? val @_s ) ch) val ea end od y =( to ?(: ns e_b po nd_ e spo . res
  • 68. Creative Commons name author URL Construction Time Again v1ctory_1s_m1ne http://www.flickr.com/photos/v1ctory_1s_m1ne/3416173688/ Microprocesseur Stéfan http://www.flickr.com/photos/st3f4n/2389606236/ chain-of-14-cubes.4 Ardonik http://www.flickr.com/photos/ardonik/3273300715/ (untitled) squacco http://www.flickr.com/photos/squeakywheel/454111821/ up there Paul Mayne http://www.flickr.com/photos/paulm/873641065/ Day 5/365 - Night Terrors Tom Lin :3= http://www.flickr.com/photos/tom_lin/3193080175/ Testing the water The Brit_2 http://www.flickr.com/photos/26686573@N00/2188837324/ High Dive Zhao Hua Xi Shi http://www.flickr.com/photos/elephantonabicycle/4321415975/
  • 70. Slides => http://bit.ly/railstoaster Спасибо @GreggPollack Gregg@EnvyLabs.com http://envylabs.com