ruby rackup:是否可以通过编程方式从另一个映射中添加一个映射?
ruby rackup: is it possible to programatically add a mapping from within another mapping?
我有一个 .ru 文件,可以毫无问题地设置映射(下面的 'register' 映射)。
但是我希望服务能够通过点击 url 来注册自己,所以我希望能够从其他映射中即时添加新映射。
下面的代码不有效。我做错了什么,这可能吗?
谢谢!
map '/register' do
run Proc.new { |env|
# inside of register i want to add another mapping.
# obviously 'bar' would be a value read out of env
map '/bar' do
run Proc.new{ |env| ['200', { 'Content-Type' => 'text/html' },'bar' }
end
[ '200', {'Content-Type' => 'text/html'}, "registered"]
}
end
根据https://rack.github.io/, "To use Rack, provide an "app": 一个object响应调用方法,以环境哈希为参数,返回一个包含三个元素的数组:
- HTTP 响应代码
- headers
的哈希值
- 响应body,必须响应
each
您的第三个元素不会响应 each
。也许将它包装在一个数组中?
我认为没有办法使用 map
在事后添加路由。一种替代方法是使用 Rack::URLMap 来定义您的应用程序。您需要维护自己的注册路由列表(作为哈希),并在每次向哈希添加新路由时调用 Rack::URLMap#remap
:
url_map = Rack::URLMap.new
routes = {
"/register" => lambda do |env|
routes["/bar"] = lambda do |env|
[ "200", {"Content-Type" => "text/plain"}, ["bar"] ]
end
url_map.remap(routes)
[ "200", {"Content-Type" => "text/plain"}, ["registered"] ]
end
}
url_map.remap(routes)
run url_map
请注意,您可以只使用散列,但 URLMap 提供了一些不错的便利,包括 404 处理。如果你有五分钟的空闲时间,它实际上是一个非常好的 class 和 worth reading。
如果你愿意,你可以把它变成一个整洁的小东西 class:
class Application
def initialize
@routes = {}
@url_map = Rack::URLMap.new
register_route "/register" do |env|
# When "/register" is requested, register the new route "/bar"
register_route "/bar" do |env|
[ 200, {"Content-Type" => "text/plain"}, ["bar"] ]
end
[ 200, {"Content-Type" => "text/plain"}, ["registered"] ]
end
end
def call(env)
@url_map.call(env)
end
private
def register_route(path, &block)
@routes[path] = block
@url_map.remap(@routes)
end
end
run Application.new
我有一个 .ru 文件,可以毫无问题地设置映射(下面的 'register' 映射)。
但是我希望服务能够通过点击 url 来注册自己,所以我希望能够从其他映射中即时添加新映射。
下面的代码不有效。我做错了什么,这可能吗?
谢谢!
map '/register' do
run Proc.new { |env|
# inside of register i want to add another mapping.
# obviously 'bar' would be a value read out of env
map '/bar' do
run Proc.new{ |env| ['200', { 'Content-Type' => 'text/html' },'bar' }
end
[ '200', {'Content-Type' => 'text/html'}, "registered"]
}
end
根据https://rack.github.io/, "To use Rack, provide an "app": 一个object响应调用方法,以环境哈希为参数,返回一个包含三个元素的数组:
- HTTP 响应代码
- headers 的哈希值
- 响应body,必须响应
each
您的第三个元素不会响应 each
。也许将它包装在一个数组中?
我认为没有办法使用 map
在事后添加路由。一种替代方法是使用 Rack::URLMap 来定义您的应用程序。您需要维护自己的注册路由列表(作为哈希),并在每次向哈希添加新路由时调用 Rack::URLMap#remap
:
url_map = Rack::URLMap.new
routes = {
"/register" => lambda do |env|
routes["/bar"] = lambda do |env|
[ "200", {"Content-Type" => "text/plain"}, ["bar"] ]
end
url_map.remap(routes)
[ "200", {"Content-Type" => "text/plain"}, ["registered"] ]
end
}
url_map.remap(routes)
run url_map
请注意,您可以只使用散列,但 URLMap 提供了一些不错的便利,包括 404 处理。如果你有五分钟的空闲时间,它实际上是一个非常好的 class 和 worth reading。
如果你愿意,你可以把它变成一个整洁的小东西 class:
class Application
def initialize
@routes = {}
@url_map = Rack::URLMap.new
register_route "/register" do |env|
# When "/register" is requested, register the new route "/bar"
register_route "/bar" do |env|
[ 200, {"Content-Type" => "text/plain"}, ["bar"] ]
end
[ 200, {"Content-Type" => "text/plain"}, ["registered"] ]
end
end
def call(env)
@url_map.call(env)
end
private
def register_route(path, &block)
@routes[path] = block
@url_map.remap(@routes)
end
end
run Application.new