Ruby-如何将上下文传递给与另一个块包装的块

时间:2019-01-25 20:57:04

标签: ruby binding sinatra block

我试图将一些上下文(绑定?传递给一个块,因为我将一个块包装到另一个块中。不知道如何做到这一点。

这是演示此代码。问题发生在包装纸上-当我不包装包装纸时,proc将获得应有的上下文。

require 'sinatra'

class MyWebApp < Sinatra::Base

  @@help = {}
  def processing_policy(policytag)
    ## do special stuff here that might end in halt()
  end

  def self.api_endpoint(http_method, uri, policytag, helptext)
    @@helptext[uri] = { policy: policytag, help: helptext }

    if policytag.nil?
      ## It's an open endpoint. Create as-is. This part works
      send(http_method, uri, &block)
    else
      ## This is an endpoint with policy processing
      send(http_method, uri) do |*args|
        processing_policy(uri,policytag,request)
        # I probably need to do some kind of binding passthru for passed block
        # How do I do that???
        block.call(*args) # Block doesn't get context things like request etc
      end
    end
  end

  api_endpoint(:post, '/open_endpoint', nil, 'Some open endpoint') do
    "Anyone can view this - you posted #{request.body.read}"
  end

  api_endpoint(:post, '/close_endpoint', 'mypolicytag', 'Closed endpoint') do
    "This is closed = #{request.body.read}"
    # Doesn't work - block.call doesn't know about request since 
    # it doesn't have context
  end

  api_endpoint(:get, '/help', nil, "Help") do
    "Help:\n\n" + 
    @@help.map do |uri, data|
      "  #{uri} - policytag: #{data[:policy]} - #{data[:help]}\n"
    end.join()
  end
end

run MyWebApp

有什么见解吗?

1 个答案:

答案 0 :(得分:1)

好的,所以我找到了答案。 我可以使用block.call(*args)代替 instance_exec(*args, &block)即可。