Ruby模块常量设置和读取

时间:2018-01-17 14:58:30

标签: ruby sinatra

我正在开发一个包含标准方法以及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不要开火吗?

1 个答案:

答案 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