Question

When I use Sinatra as Rack middleware I can do this in my Rackup file:

use MyGloriousApp.new do | le_app |
  le_app.settings.set :frobnicate, true
end

How do I accomplish the same when I need a run block at the end of the middleware chain? Something like

run MyGloriousApp.new do | le_app |
  le_app.settings.set :frobnicate, true
end
Was it helpful?

Solution 2

Just write it like these:

app = LeApp.new
app.settings.set :frobnicate, true
run app

OTHER TIPS

This is caused by the precedence of the do ...end syntax when creating a block. Your example:

run MyGloriousApp.new do | le_app |
  le_app.settings.set :frobnicate, true
end

is equivalent to:

run(MyGloriousApp.new) do | le_app |
  le_app.settings.set :frobnicate, true
end

The block is passed to the run method, rather than your app’s constructor like you intend.

One way to fix this (which also illustrates what’s happening) would be to be explicitly associate the block with the constructor using parentheses:

run(MyGloriousApp.new do | le_app |
  le_app.settings.set :frobnicate, true
end)

The {...} syntax has a higher precedence than do...end and binds to the nearest method call to its left, so you could also do this:

run MyGloriousApp.new { | le_app |
  le_app.settings.set :frobnicate, true
}

In this case the block is associated with the call to MyGloriousApp.new rather than run.

The reason the do...end syntax works with the use method is that use passes the block through to the middleware’s constructor. run doesn’t do anything with any block passed, so it is just ignored.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top