我有一个config.ru文件开始有重复的代码:
map '/route1' do run SampleApp.new end map '/route2' do run SampleApp.new end
我想将这个config.ru文件转换成自己的Rack应用程序,所以我要做的是:
map '/' do run MyApp.new end
创建自己的机架应用程序的正确方法是什么?具体来说,我如何创建一个类,以便我可以使用我的类中的map方法来定义一堆路由?
解:
这是一个工作的解决方案:
class MyApp def initialize @app = Rack::Builder.new do # copy contents of your config.ru into this block map '/route1' do run SampleApp.new end map '/route2' do run SampleApp.new end end end def call(env) @app.call(env) end end
我以前尝试过,但是无法让它工作,因为我试图将实例变量传递给地图块.例如:
def initialize @sample_app = SampleApp.new @app = Rack::Builder.new do map '/route1' do run @sample_app # will not work end end end
这不行的原因是因为传递给地图的块是evaluated in the context of a Rack::Builder
instance.
但是,如果我传递一个局部变量,它将会工作:
def initialize sample_app = SampleApp.new @app = Rack::Builder.new do map '/route1' do run sample_app # will work end end end
解决方法
config.ru中使用的DSL在
Rack::Builder
中定义.当使用config.ru时,文件的内容将传递给Builder的实例以创建Rack应用程序.你可以直接在代码中自己做.
例如,您可以使用现有config.ru的内容,并从中创建一个新类:
require 'rack' class MyApp def initialize @app = Rack::Builder.new do # copy contents of your config.ru into this block map '/route1' do run SampleApp.new end map '/route2' do run SampleApp.new end end end def call(env) @app.call(env) end end
您需要调用方法,以便您的课程是Rack应用程序,但您可以将请求转发到您使用Builder创建的应用程序.然后,您可以创建使用您的新应用程序的新config.ru:
require './my_app' run MyApp.new