Skip to content

Instantly share code, notes, and snippets.

@Olgagr
Created September 28, 2014 06:08
Show Gist options
  • Save Olgagr/4192bae863b9b6497e6f to your computer and use it in GitHub Desktop.
Save Olgagr/4192bae863b9b6497e6f to your computer and use it in GitHub Desktop.
Sinatra router implementation - not working
# This implementation causes error:
# ArgumentError: wrong number of arguments (0 for 1..3)
# config.ru:10:in `instance_eval'
# config.ru:10:in `initialize'
# config.ru:26:in `new'
# config.ru:26:in `block in inner_app'
# /Users/ograbek/.rvm/gems/ruby-2.1.2@owning_rails/gems/rack-1.5.2/lib/rack/builder.rb:55:in `instance_eval'
# /Users/ograbek/.rvm/gems/ruby-2.1.2@owning_rails/gems/rack-1.5.2/lib/rack/builder.rb:55:in `initialize'
class App
attr_accessor :routes
def initialize(&block)
@routes = {}
instance_eval &block
end
def call(env)
if routes.has_key?(env['PATH_INFO'])
[200, { "Content-Type" => 'text/html' }, [routes[env['PATH_INFO']].call]]
else
[200, { "Content-Type" => 'text/html' }, ['Default response']]
end
end
def get(path, &block)
@routes[path] = block
end
end
run App.new do
get '/hi' do
'Owning!'
end
end
@Olgagr
Copy link
Author

Olgagr commented Sep 28, 2014

If I change this lines:

run App.new do

  get '/hi' do
    'Owning!'
  end

end

into:

app = App.new do

  get '/hi' do
    'Owning!'
  end

end

run app

this implementation works. I understand that without this change instance_eval doesn't get block, but I don't know why. Is run method somehow special ?

@macournoyer
Copy link

Short answer: do is always attached the left-most method.

Here's a bit of code to explain.

a 1 do

end
# Same as
a(1) do

end

a b do

end
# Same as
a(b) do

end

a b c do

end
# Same as
a(b(c)) do

end

If you want to force c to take the block:

a b(c do

end)

However, the following works because the do operator takes precedence over =.
Meaning it will be evaluated first.
Like * would take precedence over + in 1 + 2 * 3.

x = b do

end

In your example

run App.new do

end
# Same as
run(App.new) do

end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment