Ruby - как передать некоторый контекст в блок, который я обертываю другим блоком - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь передать некоторый контекст (привязку? К блоку, поскольку я оборачиваю блок в другой. Не знаю, как это сделать.

Вот код, который демонстрирует это. Проблема возникает при переносе - когда я не переносу, процесс получает контекст так, как должен.

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 голосов
/ 26 января 2019

ОК, поэтому я нашел ответ. Вместо block.call(*args) я могу использовать instance_exec(*args, &block) и все работает.

...