我正在开发一个包含标准方法以及CLI(Thor)和API(Sinatra)的模块。我创建了一个Submodule,它包含一个继承Sinatra :: Base的类:
module Monteverde
module Activity
def self.version
"1.0.1"
end
class API < Sinatra::Base
set :port, 22340
get "/version" do
Monteverde::Activity.version
end
run! if defined? Monteverde::OPERATION
end
end
end
此“活动”从CLI(Thor)调用:
module Monteverde
class CLI < Thor
desc "api", "Start Activity API"
def api
Monteverde.const_set("OPERATION", "started")
Monteverde::Activity::API
end
desc "aversion", "Get Activity Version"
def aversion
puts Monteverde::Activity.version
end
end
end
如果我没有为Sinatra的运行添加“if”!它将自动运行并接管模块中的其余方法:
...
class API < Sinatra::Base
register Sinatra::DefaultRoutes
set :port, 22340
get "/version" do
Monteverde::Activity.version
end
run!
end
$ ruby monteverde.rb aversion
$ == Sinatra (v2.0.0) has taken the stage on 22340 for development with backup from Puma
$ ...
我的问题是,即使在调用模块之前设置了OPERATION常量,也无法识别它。
为什么不识别OPERATION,我怎样才能得到它? 当我调用模块时,还有另一种更直观/有用的方法让Sinatra不要开火吗?
答案 0 :(得分:2)
在您的API类定义中,只要您需要该文件,就会发生run!
行。如果您引用该类,则不会再次运行,因为您正尝试使用def api
方法的最后一行。
要解决此问题,您可以将run!
命令移动到方法中,然后从Thor调用它:
class API < Sinatra::Base
# ... other stuff
def self.start
run! if defined? Monteverde::OPERATION
end
end
然后在Thor文件中:
def api
Monteverde.const_set("OPERATION", "started")
Monteverde::Activity::API.start
end
你可以推断run!
是一个类方法,因为它可以在类定义的范围内调用(不在实例方法中),所以我定义了一个类方法来调用它
但是,定义def self.start
会更简单,而只是直接从Thor文件中调用run!
方法:
def api
Monteverde::Activity::API.run!
end