SlideShare uma empresa Scribd logo
1 de 148
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

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
 

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

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

Semelhante a 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
 

Semelhante a 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
 

Mais de 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
 

Mais de 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
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 

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