#6 √ resolved
Ryan Tomayko

Sinatra::Application as Sandbox / Multi-App Plumbing

Reported by Ryan Tomayko | April 15th, 2008 @ 10:30 PM | in 0.3.0 Sammy

I've been tinkering with some ideas that would make instances of Sinatra::Application capable of hosting the DSL and that lay the ground-work for running multiple Application instances together.

The basic idea is to move all DSLish methods (get, post, template, error, configures, etc) into Sinatra::Application so that blocks passed into Application#instance_eval can execute the DSL but modify the specific Application instance only.

(Pretend the block passed to Application.new was automatically instance_eval'd):

Sinatra::Application.new do
  options.sessions = true
  get '/' do
    "Hello World!"
  end
end

That might not seem very interesting at first but when combined with Rack::Builder, you can do stuff like this:

use FooMiddleWare
map '/foo' do
  run Sinatra::Application do
    options.sessions = true
    get '/' do
      'Hello Foo'
    end
  end
end
map '/bar' do
  run Sinatra::Application do
    options.sessions = false
    get '/' do
      'Hello Bar'
    end
  end
end

Generally speaking, the ability use Sinatra at a component level like this makes it a better citizen of the Rack universe.

This sounds like a fairly large change at first but when you look at Sinatra::Application today, you find a lot of the same methods that are available at top-level but with different names:

  • get, put, post, delete are one-liners that call Application#define_event.
  • error and not_found: one-liners that call Application#define_error.
  • template and layout: one-liners that call Application#template.
  • before: one-liner that calls Application#filter

We simply unify the method names in Application with the top-level. And this simplifies the top-level quite a bit: all DSL methods on (main) become simple delegators from the top-level to the default application (Sinatra::application).

I have a branch where I'm experimenting with this and other ideas but I'm not quite happy with it yet:

http://github.com/rtomayko/sinat...

I'm still rebasing and amending commits but it should serve to illustrate the general direction. Any code/concept review would be much appreciated.

Comments and changes to this ticket

  • Blake Mizerany

    Blake Mizerany April 16th, 2008 @ 11:57 AM

    I agree 110%. I've been experimenting with this as well. Let's start putting heads together. This has been a priority since before 0.2.0.

  • Simon Rozet

    Simon Rozet April 16th, 2008 @ 12:55 PM

    WOW, If I understand correctly, it'd allows me to easily (I mean, super easily) implements a DSL to generate an AtomPub server

  • Blake Mizerany

    Blake Mizerany April 16th, 2008 @ 01:13 PM

    • → State changed from “new” to “open”

    Simon, yes.

  • Ryan Tomayko

    Ryan Tomayko April 16th, 2008 @ 11:33 PM

    So I'm trying to back off a bit and take this one step at a time. I have a branch (sandbox_refactor) that limits its focus to refactoring the existing top-level methods into Sinatra::Application only:

    http://github.com/rtomayko/sinat...

    I'm happy with these changes and feel good recommending they be pulled into the mainline. No functionality is added or changed but it moves things into the right place and gets us into a position where we can do all kinds of cool stuff.

    I've also added a lot of documentation to Application and added some additional tests, so that's a nice bonus.

    Most of the other changes from the old sandbox branch have been moved onto a new "sandbox_enhance" branch. We can discuss those changes elsewhere (separate tickets or mailing list or whatever).

  • Ryan Tomayko

    Ryan Tomayko May 19th, 2008 @ 02:43 PM

    I think we can probably close this. We still need to take the next step and consider routing and whatnot but I think we could open more specific tickets for those features.

  • Ryan Tomayko

    Ryan Tomayko September 7th, 2008 @ 06:17 PM

    • → Tag cleared.
    • → State changed from “open” to “resolved”
    • → Assigned user changed from “Blake Mizerany” to “Ryan Tomayko”

    This is going to stay where it's at for the time being on the 0.3. The redux branch takes it to the next level.

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »