SlideShare a Scribd company logo
1 of 148
Download to read offline
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

Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
Sri Prasanna
 
Deterministic simulation testing
Deterministic simulation testingDeterministic simulation testing
Deterministic simulation testing
FoundationDB
 
awesome groovy
awesome groovyawesome groovy
awesome groovy
Paul King
 

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 (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

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
 
Migrating To Ruby1.9
Migrating To Ruby1.9Migrating To Ruby1.9
Migrating To Ruby1.9
tomaspavelka
 
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
 
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
 

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

CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
Wonjun Hwang
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
FIDO Alliance
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
FIDO Alliance
 

Recently uploaded (20)

CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
 
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentation
 
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Frisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdf
Frisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdfFrisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdf
Frisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdf
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development Companies
 
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage Intacct
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 

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