Reputation: 34186
I have an array of Procs, and I want to call all of them in the context of the enclosing block, and return the last value. Specifically:
require 'sinatra/base'
class App < Sinatra::Base
end
procs = [ proc{ status 200 }, proc{ 'Success!' } ]
App.send('get', '/') do
procs.map(&:call).last
end
App.run!
It errors with No method 'status'
. I expected it to behave like:
class App < Sinatra::Base
get '/' do
status 200
'Success!'
end
end
Any idea how I might do that?
Upvotes: 0
Views: 237
Reputation: 54684
You can use instance_eval
to change the binding of the procs:
App.send('get', '/') do
procs.map{|p| instance_eval(&p) }.last
end
Upvotes: 3
Reputation: 6734
You are setting procs outside the scope of App, which is where the status method is defined. So you're not getting the binding you expect. Move the definition into the class and switching to lambdas works for me. Lambdas are true closures, so this makes sense.
Consider
class App < Sinatra::Base
procs = [ -> { status 200 }, -> { 'Success!' } ]
get '/' do
procs.map(&:call).last
end
end
Upvotes: 0