What have you found for these years?

2012-02-07

sinatra pitfalls

Source extracted from Sinatra 1.3.2

MyApp.new is not an MyApp

MyApp.new.kind_of?(MyApp) # false
Sinatra has overridden the new method with the following:
# Create a new instance of the class fronted by its middleware
# pipeline. The object is guaranteed to respond to #call but may not be
# an instance of the class new was called on.
def new(*args, &bk)
  build(Rack::Builder.new, *args, &bk).to_app
end
So MyApp.new is actually an instance of Rack::Builder
Use MyApp.new! to access the original new

Every time we call MyApp.new.call it is creating two instances of MyApp

This is false:
app = MyApp.new
app.object_id.to_s ==
Rack::Test::Session.new(app).get('/object_id').body # false
given the definition of MyApp:
require 'sinatra/base'
require 'rack/test'

class MyApp < Sinatra::Base
  get '/object_id' do
    object_id.to_s
  end
end

requiring 'sinatra' *might* run the server in at_exit!

Change the above code to require 'sinatra' would cause it to launch a web server regardless any configuration in MyApp by this line in sinatra/main.rb:
at_exit { Application.run! if $!.nil? && Application.run? }
So always require 'sinatra/base' if you want to control
whether and how to launch a web server!

* * *

I won't say those are cruel enough to force me to *fork* sinatra,
but I would seriously consider it if I have my own time doing this.

For example, if anyone could sponsor....

Those tricks might help naïve programmers who only wants a working
stuff, but it would cause my pain thinking about consistency.

Or, should I say, just leave Ruby alone and embrace Haskell?

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0