SlideShare a Scribd company logo
Merb 2.0
The long march into the future
Core Merb Principles
In Depth
Performance
Requests Per Second
Thin   Mongrel
run proc do |env|
  [
    200,
    {quot;Content-Typequot; => quot;text/htmlquot;},
    quot;Hello from rackquot;
  ]
end
class QuickApp
  def call(env)
    [
      200,
      {quot;Content-Typequot; => quot;text/htmlquot;},
      quot;Hello from rackquot;
    ]
  end
end

run QuickApp.new
class QuickApp
  def call(env)
    [
      200,
      {quot;Content-Typequot; => quot;text/htmlquot;},
      quot;Hello from rackquot;
    ]
  end
end

run QuickApp.new
Thin   Mongrel
match(quot;/routerquot;).defer_to do |req, res|
  [
    200,
    {quot;Content-Typequot; => quot;text/htmlquot;},
    quot;Helloquot;
  ]
end
Thin   Mongrel
class MyApp < Application

  def string
    quot;Stringquot;
  end

end
class MyApp < Application

  def string
    quot;Stringquot;
  end

end
Thin   Mongrel
class MyApp < Application

  def index
    render
  end

  def string
    quot;Stringquot;
  end

end
class MyApp < Application

  def index
    render
  end

  def string
    quot;Stringquot;
  end

end
Close to the metal as possible
Close to the metal as you want
Performance Testing
KCacheGrind
use Merb::Rack::Profile
profile/url/callgrind.out.time
5% or greater
10% or greater
10% or greater


          Merb::RenderMixin::_get_layout
                        10.05 %
Mini-demo
Concurrency
20




16




12




 8




 4




 0
     1   2   4       8       16      32




                 Ideal concurrency curve
1 request in 16ms (16ms/req)
2 requests in 16ms (8ms/req)
4 requests in 16ms (4ms/req)
8 requests in 16ms (2ms/req)
16 requests in 16ms (1ms/req)
32 requests in 16ms (2req/ms)
20




16




12




 8




 4




 0
     1   2   4       8       16      32




                 Ideal concurrency curve
Chart 10
15.00


11.25


 7.50


 3.75


   0
        1   2     4      8     16    32




                Merb MRI concurrency curve
Chart 12
15.00


11.25


 7.50


 3.75


   0
        1      2      4      8    16     32




        Merb JRuby (Mongrel) concurrency curve
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2    4    8      16   32   64   128   256




                Merb Glassfish concurrency curve
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                                           Not ideal
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                                           Not ideal
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                           Not ideal (but it works)
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                           Not ideal (but it works)
Threadsafety
Merb::Config[:use_mutex]
class User
  cattr_accessor :current
end

class Foo < Merb::Controller
  before do
    User.current = session.user
  end
end
class User
  cattr_accessor :current
end

class Foo <  FAIL
            Merb::Controller
  before do
    User.current = session.user
  end
end
Shared state hurts puppies
Solutions
Thread-local
class User
  def self.current=(user)
    Thread.current[:user] = user
  end

  def self.current
    Thread.current[:user]
  end
end

class Foo < Merb::Controller
  before do
    User.current = session.user
  end
end
Using a Hash across threads
Hash {:x => 5}
Hash {:x => 5}

Thread 1                    Thread 2
Hash {:x => 5}

Thread 1                    Thread 2
Hash {:x => 5}

Thread 1                    Thread 2

Read x
Hash {:x => 5}

Thread 1                    Thread 2

Read x                 Write x=”1”
Hash {:x => 5}

Thread 1                    Thread 2

Read x                 Write x=”1”
                             clear x
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x                Write x=”1”
                               clear x
is there an x?
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x                Write x=”1”
                               clear x
is there an x?
no? return nil                 x=1
Mutex
Hash {:x => 5}
Hash {:x => 5}

Thread 1                    Thread 2
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x


is there an x?
yes? return 5
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x                Write x=”1”
                               clear x
is there an x?
yes? return 5                  x=1
Hash {:x => 5}
Hash {:x => 5}

Thread 1                    Thread 2
Hash {:x => 5}

Thread 1                    Thread 2

                       Write x=”1”
                             clear x


                             x=1
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x                Write x=”1”
                               clear x
is there an x?
yes? return 1                  x=1
Mutexes make non-atomic
operations atomic
Modularity
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gems_version
dependency   quot;merb-assetsquot;, merb_gems_version
dependency   quot;merb-cachequot;, merb_gems_version
dependency   quot;merb-helpersquot;, merb_gems_version
dependency   quot;merb-mailerquot;, merb_gems_version
dependency   quot;merb-slicesquot;, merb_gems_version
dependency   quot;merb-auth-corequot;, merb_gems_version
dependency   quot;merb-auth-morequot;, merb_gems_version
dependency   quot;merb-auth-slice-passwordquot;, merb_gems_version
dependency   quot;merb-param-protectionquot;, merb_gems_version
dependency   quot;merb-exceptionsquot;, merb_gems_version

dependency   quot;dm-corequot;, dm_gems_version
dependency   quot;dm-aggregatesquot;, dm_gems_version
dependency   quot;dm-migrationsquot;, dm_gems_version
dependency   quot;dm-timestampsquot;, dm_gems_version
dependency   quot;dm-typesquot;, dm_gems_version
dependency   quot;dm-validationsquot;, dm_gems_version
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gems_version
dependency   quot;merb-assetsquot;, merb_gems_version
dependency   quot;merb-cachequot;, merb_gems_version
dependency   quot;merb-helpersquot;, merb_gems_version
dependency   quot;merb-mailerquot;, merb_gems_version
dependency   quot;merb-slicesquot;, merb_gems_version
dependency   quot;merb-auth-corequot;, merb_gems_version
dependency   quot;merb-auth-morequot;, merb_gems_version
dependency   quot;merb-auth-slice-passwordquot;, merb_gems_version
dependency   quot;merb-param-protectionquot;, merb_gems_version
dependency   quot;merb-exceptionsquot;, merb_gems_version

dependency   quot;dm-corequot;, dm_gems_version
dependency   quot;dm-aggregatesquot;, dm_gems_version
dependency   quot;dm-migrationsquot;, dm_gems_version
dependency   quot;dm-timestampsquot;, dm_gems_version
dependency   quot;dm-typesquot;, dm_gems_version
dependency   quot;dm-validationsquot;, dm_gems_version
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gems_version
dependency   quot;merb-assetsquot;, merb_gems_version
dependency   quot;merb-cachequot;, merb_gems_version
dependency   quot;merb-helpersquot;, merb_gems_version
dependency   quot;merb-mailerquot;, merb_gems_version
dependency   quot;merb-slicesquot;, merb_gems_version
dependency   quot;merb-auth-corequot;, merb_gems_version
dependency   quot;merb-auth-morequot;, merb_gems_version
dependency   quot;merb-auth-slice-passwordquot;, merb_gems_version
dependency   quot;merb-param-protectionquot;, merb_gems_version
dependency   quot;merb-exceptionsquot;, merb_gems_version

dependency   quot;dm-corequot;, dm_gems_version
dependency   quot;dm-aggregatesquot;, dm_gems_version
dependency   quot;dm-migrationsquot;, dm_gems_version
dependency   quot;dm-timestampsquot;, dm_gems_version
dependency   quot;dm-typesquot;, dm_gems_version
dependency   quot;dm-validationsquot;, dm_gems_version
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gems_version
dependency   quot;merb-assetsquot;, merb_gems_version
dependency   quot;merb-cachequot;, merb_gems_version
dependency   quot;merb-helpersquot;, merb_gems_version
dependency   quot;merb-mailerquot;, merb_gems_version
dependency
dependency
             quot;merb-slicesquot;, merb_gems_version

                                1 .1.4
             quot;merb-auth-corequot;, merb_gems_version
dependency
                        uby
             quot;merb-auth-morequot;, merb_gems_version
dependency
dependency          J R
             quot;merb-auth-slice-passwordquot;, merb_gems_version
             quot;merb-param-protectionquot;, merb_gems_version
dependency   quot;merb-exceptionsquot;, merb_gems_version

dependency   quot;dm-corequot;, dm_gems_version
dependency   quot;dm-aggregatesquot;, dm_gems_version
dependency   quot;dm-migrationsquot;, dm_gems_version
dependency   quot;dm-timestampsquot;, dm_gems_version
dependency   quot;dm-typesquot;, dm_gems_version
dependency   quot;dm-validationsquot;, dm_gems_version
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gems_version
dependency   quot;merb-assetsquot;, merb_gems_version
dependency   quot;merb-cachequot;, merb_gems_version
dependency   quot;merb-helpersquot;, merb_gems_version
dependency   quot;merb-mailerquot;, merb_gems_version
dependency   quot;merb-slicesquot;, merb_gems_version
dependency   quot;merb-auth-corequot;, merb_gems_version
dependency   quot;merb-auth-morequot;, merb_gems_version
dependency   quot;merb-auth-slice-passwordquot;, merb_gems_version
dependency   quot;merb-param-protectionquot;, merb_gems_version
dependency   quot;merb-exceptionsquot;, merb_gems_version

dependency   quot;dm-corequot;, dm_gems_version
dependency   quot;dm-aggregatesquot;, dm_gems_version
dependency   quot;dm-migrationsquot;, dm_gems_version
dependency   quot;dm-timestampsquot;, dm_gems_version
dependency   quot;dm-typesquot;, dm_gems_version
dependency   quot;dm-validationsquot;, dm_gems_version
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gems_version
dependency   quot;merb-assetsquot;, merb_gems_version
dependency   quot;merb-cachequot;, merb_gems_version
dependency   quot;merb-helpersquot;, merb_gems_version
dependency   quot;merb-mailerquot;, merb_gems_version
dependency
                                   .5+
             quot;merb-slicesquot;, merb_gems_version
dependency
                          1      .1
             quot;merb-auth-corequot;, merb_gems_version
dependency
dependency             by
             quot;merb-auth-morequot;, merb_gems_version

                     Ru
             quot;merb-auth-slice-passwordquot;, merb_gems_version
dependency         J
             quot;merb-param-protectionquot;, merb_gems_version
dependency   quot;merb-exceptionsquot;, merb_gems_version

dependency   quot;dm-corequot;, dm_gems_version
dependency   quot;dm-aggregatesquot;, dm_gems_version
dependency   quot;dm-migrationsquot;, dm_gems_version
dependency   quot;dm-timestampsquot;, dm_gems_version
dependency   quot;dm-typesquot;, dm_gems_version
dependency   quot;dm-validationsquot;, dm_gems_version
@overridable
# This is a stub method so plugins can
# implement param filtering if they want.
#
# ==== Parameters
# params<Hash{Symbol => String}>::
#   A list of params
#
# ==== Returns
# Hash{Symbol => String}::
#   A new list of params, filtered as desired
#
# :api: plugin
# @overridable
def self._filter_params(params)
  params
end
class Articles < Application
  params_accessible :article =>
    [:title, :body]
end
class Articles < Application
  params_accessible :article =>
    [:title, :body]
end
class Articles < Application
  def self._filter_params(params)
    # deep_clone
    ret =
      Marshal.load(Marshal.dump(params))

    ret[:post].reject! do |k,v|
      !k.in?(:title, :body)
    end
  end
end
class Articles < Application
  def self._filter_params(params)
    # deep_clone
    ret =
      Marshal.load(Marshal.dump(params))

    ret[:post].reject! do |k,v|
      !k.in?(:title, :body)
    end
  end
end
# :api: public
# @overridable
def _template_location(ctx, type, ctrlr)
  _conditionally_append_extension(
    ctrlr ?
    quot;#{ctrlr}/#{ctx}quot; :
    quot;#{ctx}quot;, type)
end
class Articles < Application
  def self._template_location(
    ctx, type, ctrlr)

    quot;#{ctrlr}.#{ctx}.#{type}quot;
  end
end
class Articles < Application
  def self._template_location(
    ctx, type, ctrlr)

    quot;#{ctrlr}.#{ctx}.#{type}quot;
  end
end
class Articles < Application
  def self._template_location(
                       t”
                   ay
    ctx, type, ctrlr)
                 l   ou
                  r= “
            ro lle
         nt
    quot;#{ctrlr}.#{ctx}.#{type}quot;
      co
  end
end
class Articles < Application
  self.template_roots = [
    [
       Merb.root / quot;appquot; / quot;viewsquot;,
       :_template_location
    ],
    [
       Merb.root / quot;my_viewsquot;,
       :_my_template_location
    ]
  ]
end
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/
merb-auth-slice-password-1.0.4/app/
viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/
test/awesome/slices/merb-auth-slice-password/app/
viewsquot;, :_slice_template_location]]
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/
merb-auth-slice-password-1.0.4/app/
viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/
test/awesome/slices/merb-auth-slice-password/app/
viewsquot;, :_slice_template_location]]
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/
merb-auth-slice-password-1.0.4/app/
viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/
test/awesome/slices/merb-auth-slice-password/app/
viewsquot;, :_slice_template_location]]
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/
merb-auth-slice-password-1.0.4/app/
viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/
test/awesome/slices/merb-auth-slice-password/app/
viewsquot;, :_slice_template_location]]
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/
merb-auth-slice-password-1.0.4/app/
viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/
test/awesome/slices/merb-auth-slice-password/app/
viewsquot;, :_slice_template_location]]
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/
merb-auth-slice-password-1.0.4/app/
viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/
test/awesome/slices/merb-auth-slice-password/app/
viewsquot;, :_slice_template_location]]
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/
merb-auth-slice-password-1.0.4/app/
viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/
test/awesome/slices/merb-auth-slice-password/app/
viewsquot;, :_slice_template_location]]
def _slice_template_location(ctx, type, ctrlr)
  if ctrlr && ctrlr.include?('/')
    # skip first segment if given (which is the module name)
    segments = ctrlr.split('/')
    quot;#{segments[1,segments.length-1].join('/')}/#{ctx}.#{type}quot;
  else
    # default template location logic
    _template_location(ctx, type, ctrlr)
  end
end
Templates
def load_template_io(path)
  file = Dir[
    quot;#{path}.{#{template_extensions.join(',')}}quot;
  ].first
  File.open(file, quot;rquot;) if file
end
def load_template_io(path)
  templates = {
    Merb.root / quot;appquot; / quot;viewsquot; / quot;template_ioquot; /
      quot;index.html.erbquot; => quot;Hello worldquot;,
    Merb.root / quot;appquot; / quot;viewsquot; / quot;template_ioquot; /
      quot;two.html.erbquot; => quot;Twoquot;
  }

  if templates[path + quot;.erbquot;]
    VirtualFile.new(templates[path + quot;.erbquot;], path + quot;.erbquot;)
  else
    file = Dir[
      quot;#{path}.{#{template_extensions.join(',')}}quot;
    ].first
    File.open(file, quot;rquot;) if file
  end
end
Merb::Router.prepare {default_routes}

class TemplateIo < Merb::Controller
  def index
    render
  end

  def two
    render
  end
end
Quick demo
Good Ruby citizen
Rubygems
Rubygems :(
Rubygems -- but getting :)
Working with community ==
helping the community
Rack
Rack middleware
Where is this going?
Apps as a first-class concept
module MyApp
  class TemplateIo < Application
    def index
      render
    end

    def two
      render
    end
  end
end
module MyApp
  class TemplateIo < Application
    def index
      render
    end

    def two
      render
    end
  end
end
module MyApp
  class TemplateIo < Application
    def index
      render        MyApp::Application
    end

    def two
      render
    end
  end
end
module MyApp
  extend Merb::App

 mount ::Blog, :at => quot;/blogquot;

  Config[:framework] = flat
end
Blog::Config[:log_delimiter] = quot;BLOG: quot;
Admin Application/Framework
CMS Application
DB Admin Application
Slices on Steroids
Resources as a
first-class concept
module MyApp
  class Resource < Merb::Resource
    def list(klass)
      klass.all
    end

    def get(klass, ids)
      klass.get(ids)
    end

    def authorized?(namespace, *args)
      user == quot;wycatsquot;
    end

    def user
      request.session.user
    end
  end
end
Why?
DRYing up common idioms
Increasing flexibility
(where needed)
Core principle:
Simple cases can’t get harder
Further improve merb server
Short term
Long term
Dynamic worker pools
Remove need for nginx
Self-managing cluster
Additional modules
i18n
l10n
Feed syndication
Flat pages
More powerful router
Router directly to a view
even better resource()
Framework for OSS Apps
Authentication
User Management
Authorization
Note:
Communication primitives
Tailored stacks
Designers
Web shops

More Related Content

What's hot

The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
Frank Lyaruu
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)
Alexey Fyodorov
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
BoneyGawande
 
Non-blocking synchronization — what is it and why we (don't?) need it
Non-blocking synchronization — what is it and why we (don't?) need itNon-blocking synchronization — what is it and why we (don't?) need it
Non-blocking synchronization — what is it and why we (don't?) need it
Alexey Fyodorov
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
Sri Prasanna
 
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018 Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Codemotion
 
Java micro optimizations 2017
Java micro optimizations 2017Java micro optimizations 2017
Java micro optimizations 2017
Dmitriy Dumanskiy
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
Arturo Herrero
 
Deterministic simulation testing
Deterministic simulation testingDeterministic simulation testing
Deterministic simulation testing
FoundationDB
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
Angel Garcia Olloqui
 
WebSphere Message Broker v6.x Overview - 2008-01-09
WebSphere Message Broker v6.x Overview - 2008-01-09WebSphere Message Broker v6.x Overview - 2008-01-09
WebSphere Message Broker v6.x Overview - 2008-01-09
Mårten Gustafson
 
JS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.js
JS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.jsJS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.js
JS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.js
JSFestUA
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
James Croft
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
James Croft
 
Grails Transactions
Grails TransactionsGrails Transactions
Grails Transactions
Burt Beckwith
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
Iram Ramrajkar
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code Development
Peter Gfader
 
awesome groovy
awesome groovyawesome groovy
awesome groovy
Paul King
 
Javascript The Good Parts
Javascript The Good PartsJavascript The Good Parts
Javascript The Good Parts
Federico Galassi
 

What's hot (19)

The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
 
Non-blocking synchronization — what is it and why we (don't?) need it
Non-blocking synchronization — what is it and why we (don't?) need itNon-blocking synchronization — what is it and why we (don't?) need it
Non-blocking synchronization — what is it and why we (don't?) need it
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
 
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018 Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
 
Java micro optimizations 2017
Java micro optimizations 2017Java micro optimizations 2017
Java micro optimizations 2017
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Deterministic simulation testing
Deterministic simulation testingDeterministic simulation testing
Deterministic simulation testing
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
WebSphere Message Broker v6.x Overview - 2008-01-09
WebSphere Message Broker v6.x Overview - 2008-01-09WebSphere Message Broker v6.x Overview - 2008-01-09
WebSphere Message Broker v6.x Overview - 2008-01-09
 
JS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.js
JS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.jsJS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.js
JS Fest 2019. Thomas Watson. Post-Mortem Debugging in Node.js
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
 
Grails Transactions
Grails TransactionsGrails Transactions
Grails Transactions
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code Development
 
awesome groovy
awesome groovyawesome groovy
awesome groovy
 
Javascript The Good Parts
Javascript The Good PartsJavascript The Good Parts
Javascript The Good Parts
 

Viewers also liked

Merb jQuery
Merb jQueryMerb jQuery
Merb jQuery
Yehuda Katz
 
Vaporware To Awesome
Vaporware To AwesomeVaporware To Awesome
Vaporware To Awesome
Yehuda Katz
 
Testing Merb
Testing MerbTesting Merb
Testing Merb
Yehuda Katz
 
Why You Shouldn't Write OO
Why You Shouldn't Write OO Why You Shouldn't Write OO
Why You Shouldn't Write OO
Yehuda Katz
 
Making your oss project more like rails
Making your oss project more like railsMaking your oss project more like rails
Making your oss project more like rails
Yehuda Katz
 

Viewers also liked (6)

Appnovation One Sheet
Appnovation One SheetAppnovation One Sheet
Appnovation One Sheet
 
Merb jQuery
Merb jQueryMerb jQuery
Merb jQuery
 
Vaporware To Awesome
Vaporware To AwesomeVaporware To Awesome
Vaporware To Awesome
 
Testing Merb
Testing MerbTesting Merb
Testing Merb
 
Why You Shouldn't Write OO
Why You Shouldn't Write OO Why You Shouldn't Write OO
Why You Shouldn't Write OO
 
Making your oss project more like rails
Making your oss project more like railsMaking your oss project more like rails
Making your oss project more like rails
 

Similar to Merb Day Keynote

A Re-Introduction to JavaScript
A Re-Introduction to JavaScriptA Re-Introduction to JavaScript
A Re-Introduction to JavaScript
Simon Willison
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
Marc Chung
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)
Benjamin Bock
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
Wen-Tien Chang
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
kyleburton
 
Functional Concepts for OOP Developers
Functional Concepts for OOP DevelopersFunctional Concepts for OOP Developers
Functional Concepts for OOP Developers
brweber2
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Jesse Vincent
 
JavaScript Beginner Tutorial | WeiYuan
JavaScript Beginner Tutorial | WeiYuanJavaScript Beginner Tutorial | WeiYuan
JavaScript Beginner Tutorial | WeiYuan
Wei-Yuan Chang
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
guestaef7ea
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
Jesse Vincent
 
Matlab programming
Matlab programmingMatlab programming
Matlab programming
Md. Rayid Hasan Mojumder
 
Perly Parsing with Regexp::Grammars
Perly Parsing with Regexp::GrammarsPerly Parsing with Regexp::Grammars
Perly Parsing with Regexp::Grammars
Workhorse Computing
 
MySQL Proxy tutorial
MySQL Proxy tutorialMySQL Proxy tutorial
MySQL Proxy tutorial
Giuseppe Maxia
 
Migrating To Ruby1.9
Migrating To Ruby1.9Migrating To Ruby1.9
Migrating To Ruby1.9
tomaspavelka
 
Intro to J Ruby
Intro to J RubyIntro to J Ruby
Intro to J Ruby
Frederic Jean
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
lachie
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
zhang tao
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)
err
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
kwatch
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
elliando dias
 

Similar to Merb Day Keynote (20)

A Re-Introduction to JavaScript
A Re-Introduction to JavaScriptA Re-Introduction to JavaScript
A Re-Introduction to JavaScript
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
 
Functional Concepts for OOP Developers
Functional Concepts for OOP DevelopersFunctional Concepts for OOP Developers
Functional Concepts for OOP Developers
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
JavaScript Beginner Tutorial | WeiYuan
JavaScript Beginner Tutorial | WeiYuanJavaScript Beginner Tutorial | WeiYuan
JavaScript Beginner Tutorial | WeiYuan
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
 
Matlab programming
Matlab programmingMatlab programming
Matlab programming
 
Perly Parsing with Regexp::Grammars
Perly Parsing with Regexp::GrammarsPerly Parsing with Regexp::Grammars
Perly Parsing with Regexp::Grammars
 
MySQL Proxy tutorial
MySQL Proxy tutorialMySQL Proxy tutorial
MySQL Proxy tutorial
 
Migrating To Ruby1.9
Migrating To Ruby1.9Migrating To Ruby1.9
Migrating To Ruby1.9
 
Intro to J Ruby
Intro to J RubyIntro to J Ruby
Intro to J Ruby
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 

More from Yehuda Katz

Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
Yehuda Katz
 
Writing Fast Client-Side Code: Lessons Learned from SproutCore
Writing Fast Client-Side Code: Lessons Learned from SproutCoreWriting Fast Client-Side Code: Lessons Learned from SproutCore
Writing Fast Client-Side Code: Lessons Learned from SproutCore
Yehuda Katz
 
SproutCore: Amber
SproutCore: AmberSproutCore: Amber
SproutCore: Amber
Yehuda Katz
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Organizing jQuery Projects Without OO
Organizing jQuery Projects Without OOOrganizing jQuery Projects Without OO
Organizing jQuery Projects Without OO
Yehuda Katz
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
Yehuda Katz
 
Merb Camp Keynote
Merb Camp KeynoteMerb Camp Keynote
Merb Camp Keynote
Yehuda Katz
 
Merb
MerbMerb
DataMapper
DataMapperDataMapper
DataMapper
Yehuda Katz
 
jQuery and Ruby Web Frameworks
jQuery and Ruby Web FrameworksjQuery and Ruby Web Frameworks
jQuery and Ruby Web Frameworks
Yehuda Katz
 
jQuery Presentation to Rails Developers
jQuery Presentation to Rails DevelopersjQuery Presentation to Rails Developers
jQuery Presentation to Rails Developers
Yehuda Katz
 

More from Yehuda Katz (11)

Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
 
Writing Fast Client-Side Code: Lessons Learned from SproutCore
Writing Fast Client-Side Code: Lessons Learned from SproutCoreWriting Fast Client-Side Code: Lessons Learned from SproutCore
Writing Fast Client-Side Code: Lessons Learned from SproutCore
 
SproutCore: Amber
SproutCore: AmberSproutCore: Amber
SproutCore: Amber
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Organizing jQuery Projects Without OO
Organizing jQuery Projects Without OOOrganizing jQuery Projects Without OO
Organizing jQuery Projects Without OO
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Merb Camp Keynote
Merb Camp KeynoteMerb Camp Keynote
Merb Camp Keynote
 
Merb
MerbMerb
Merb
 
DataMapper
DataMapperDataMapper
DataMapper
 
jQuery and Ruby Web Frameworks
jQuery and Ruby Web FrameworksjQuery and Ruby Web Frameworks
jQuery and Ruby Web Frameworks
 
jQuery Presentation to Rails Developers
jQuery Presentation to Rails DevelopersjQuery Presentation to Rails Developers
jQuery Presentation to Rails Developers
 

Recently uploaded

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
TIPNGVN2
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 

Recently uploaded (20)

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 

Merb Day Keynote

  • 1. Merb 2.0 The long march into the future
  • 6. Thin Mongrel
  • 7. run proc do |env| [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end
  • 8. class QuickApp def call(env) [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end end run QuickApp.new
  • 9. class QuickApp def call(env) [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end end run QuickApp.new
  • 10. Thin Mongrel
  • 11. match(quot;/routerquot;).defer_to do |req, res| [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Helloquot; ] end
  • 12. Thin Mongrel
  • 13. class MyApp < Application def string quot;Stringquot; end end
  • 14. class MyApp < Application def string quot;Stringquot; end end
  • 15. Thin Mongrel
  • 16. class MyApp < Application def index render end def string quot;Stringquot; end end
  • 17. class MyApp < Application def index render end def string quot;Stringquot; end end
  • 18. Close to the metal as possible
  • 19. Close to the metal as you want
  • 26. 10% or greater Merb::RenderMixin::_get_layout 10.05 %
  • 29. 20 16 12 8 4 0 1 2 4 8 16 32 Ideal concurrency curve
  • 30. 1 request in 16ms (16ms/req)
  • 31. 2 requests in 16ms (8ms/req)
  • 32. 4 requests in 16ms (4ms/req)
  • 33. 8 requests in 16ms (2ms/req)
  • 34. 16 requests in 16ms (1ms/req)
  • 35. 32 requests in 16ms (2req/ms)
  • 36. 20 16 12 8 4 0 1 2 4 8 16 32 Ideal concurrency curve
  • 37. Chart 10 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 Merb MRI concurrency curve
  • 38. Chart 12 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 Merb JRuby (Mongrel) concurrency curve
  • 39. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Merb Glassfish concurrency curve
  • 40. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal
  • 41. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal
  • 42. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal (but it works)
  • 43. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal (but it works)
  • 46. class User cattr_accessor :current end class Foo < Merb::Controller before do User.current = session.user end end
  • 47. class User cattr_accessor :current end class Foo < FAIL Merb::Controller before do User.current = session.user end end
  • 51. class User def self.current=(user) Thread.current[:user] = user end def self.current Thread.current[:user] end end class Foo < Merb::Controller before do User.current = session.user end end
  • 52. Using a Hash across threads
  • 54. Hash {:x => 5} Thread 1 Thread 2
  • 55. Hash {:x => 5} Thread 1 Thread 2
  • 56. Hash {:x => 5} Thread 1 Thread 2 Read x
  • 57. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1”
  • 58. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x
  • 59. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x?
  • 60. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? no? return nil x=1
  • 61. Mutex
  • 63. Hash {:x => 5} Thread 1 Thread 2
  • 64. Hash {:x => 5} Thread 1 Thread 2 Read x is there an x? yes? return 5
  • 65. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? yes? return 5 x=1
  • 67. Hash {:x => 5} Thread 1 Thread 2
  • 68. Hash {:x => 5} Thread 1 Thread 2 Write x=”1” clear x x=1
  • 69. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? yes? return 1 x=1
  • 72. merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
  • 73. merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
  • 74. merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
  • 75. merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency dependency quot;merb-slicesquot;, merb_gems_version 1 .1.4 quot;merb-auth-corequot;, merb_gems_version dependency uby quot;merb-auth-morequot;, merb_gems_version dependency dependency J R quot;merb-auth-slice-passwordquot;, merb_gems_version quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
  • 76. merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
  • 77. merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency .5+ quot;merb-slicesquot;, merb_gems_version dependency 1 .1 quot;merb-auth-corequot;, merb_gems_version dependency dependency by quot;merb-auth-morequot;, merb_gems_version Ru quot;merb-auth-slice-passwordquot;, merb_gems_version dependency J quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
  • 79. # This is a stub method so plugins can # implement param filtering if they want. # # ==== Parameters # params<Hash{Symbol => String}>:: # A list of params # # ==== Returns # Hash{Symbol => String}:: # A new list of params, filtered as desired # # :api: plugin # @overridable def self._filter_params(params) params end
  • 80. class Articles < Application params_accessible :article => [:title, :body] end
  • 81. class Articles < Application params_accessible :article => [:title, :body] end
  • 82. class Articles < Application def self._filter_params(params) # deep_clone ret = Marshal.load(Marshal.dump(params)) ret[:post].reject! do |k,v| !k.in?(:title, :body) end end end
  • 83. class Articles < Application def self._filter_params(params) # deep_clone ret = Marshal.load(Marshal.dump(params)) ret[:post].reject! do |k,v| !k.in?(:title, :body) end end end
  • 84. # :api: public # @overridable def _template_location(ctx, type, ctrlr) _conditionally_append_extension( ctrlr ? quot;#{ctrlr}/#{ctx}quot; : quot;#{ctx}quot;, type) end
  • 85. class Articles < Application def self._template_location( ctx, type, ctrlr) quot;#{ctrlr}.#{ctx}.#{type}quot; end end
  • 86. class Articles < Application def self._template_location( ctx, type, ctrlr) quot;#{ctrlr}.#{ctx}.#{type}quot; end end
  • 87. class Articles < Application def self._template_location( t” ay ctx, type, ctrlr) l ou r= “ ro lle nt quot;#{ctrlr}.#{ctx}.#{type}quot; co end end
  • 88. class Articles < Application self.template_roots = [ [ Merb.root / quot;appquot; / quot;viewsquot;, :_template_location ], [ Merb.root / quot;my_viewsquot;, :_my_template_location ] ] end
  • 89. >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
  • 90. >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
  • 91. >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
  • 92. >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
  • 93. >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
  • 94. >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
  • 95. >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
  • 96. def _slice_template_location(ctx, type, ctrlr) if ctrlr && ctrlr.include?('/') # skip first segment if given (which is the module name) segments = ctrlr.split('/') quot;#{segments[1,segments.length-1].join('/')}/#{ctx}.#{type}quot; else # default template location logic _template_location(ctx, type, ctrlr) end end
  • 98. def load_template_io(path) file = Dir[ quot;#{path}.{#{template_extensions.join(',')}}quot; ].first File.open(file, quot;rquot;) if file end
  • 99. def load_template_io(path) templates = { Merb.root / quot;appquot; / quot;viewsquot; / quot;template_ioquot; / quot;index.html.erbquot; => quot;Hello worldquot;, Merb.root / quot;appquot; / quot;viewsquot; / quot;template_ioquot; / quot;two.html.erbquot; => quot;Twoquot; } if templates[path + quot;.erbquot;] VirtualFile.new(templates[path + quot;.erbquot;], path + quot;.erbquot;) else file = Dir[ quot;#{path}.{#{template_extensions.join(',')}}quot; ].first File.open(file, quot;rquot;) if file end end
  • 100. Merb::Router.prepare {default_routes} class TemplateIo < Merb::Controller def index render end def two render end end
  • 105. Rubygems -- but getting :)
  • 106. Working with community == helping the community
  • 107. Rack
  • 109. Where is this going?
  • 110. Apps as a first-class concept
  • 111. module MyApp class TemplateIo < Application def index render end def two render end end end
  • 112. module MyApp class TemplateIo < Application def index render end def two render end end end
  • 113. module MyApp class TemplateIo < Application def index render MyApp::Application end def two render end end end
  • 114. module MyApp extend Merb::App mount ::Blog, :at => quot;/blogquot; Config[:framework] = flat end
  • 121. module MyApp class Resource < Merb::Resource def list(klass) klass.all end def get(klass, ids) klass.get(ids) end def authorized?(namespace, *args) user == quot;wycatsquot; end def user request.session.user end end end
  • 122.
  • 123. Why?
  • 124. DRYing up common idioms
  • 126. Core principle: Simple cases can’t get harder
  • 131. Remove need for nginx
  • 134. i18n
  • 135. l10n