【问题标题】:Another way for global variable in Ruby and SinatraRuby 和 Sinatra 中全局变量的另一种方式
【发布时间】:2016-05-01 13:43:51
【问题描述】:

我在我的应用程序中使用 Ruby 和 Sinatra。

我想分配一个将在不同的类和方法中使用的变量。

在我的应用程序文件中,即“Millennium”是我的应用程序名称,因此应用程序文件为 millennium.rb 包含:

require 'rubygems'
require 'sinatra'
require 'yaml'
require 'active_record'
require 'sidekiq'
require 'statsd'

custom_statsd = Statsd.new('localhost', 8125)  #custom_statsd available across the application. 

class Millennium < Sinatra::Application
  set :use_queueing_in_dev, false # useful for debugging queue issues.
  set :protection, :except => [:json_csrf]

  configure do
    # These allow our error handlers to capture the errors
    disable :raise_errors
    disable :show_exceptions
    enable :logging
  end

  before do
    #logger.info request.body.read
    request.body.rewind
  end
end

在这里,我想在我的应用程序的任何类中使用 custom_statsd 变量的值。

我认为使用“$”不是一个好主意。请建议我这样做的另一种方法是什么。

谢谢!!!!

【问题讨论】:

    标签: ruby-on-rails ruby sinatra


    【解决方案1】:

    将实例放在共享配置模块中的类变量中可能会稍微好一点,如下所示:

    module MyAppConfig
      def self.statsd
        @statsd ||= Statsd.new('localhost', 8125)
      end
    end
    
    class SomeOtherThing
      def log!
        MyAppConfig.statsd.something('hey')
      end
    end
    
    SomeOtherThing.new.log!
    

    【讨论】:

      【解决方案2】:

      一般不建议使用全局变量,但在某些情况下它是最简单的最好方法,只是不要过度使用它。 我建议在这里使用单个常量作为命名空间,从 yaml 配置文件初始化。

      CONFIG = YAML::load_file("./config.yaml")
      
      to_monitor CONFIG.monitor.osign_job_id
      

      这里是 config.yaml

      --- !ruby/struct
        zf: 999
        debug_level: DEBUG # available log levels are: DEBUG, INFO, WARN, ERROR and  FATAL 
        :monitor: !ruby/struct
          osign_job_id: 86
      

      【讨论】:

      • 嘿 Jesper,为什么不呢?
      • 我的两分钱:一方面,它是不必要的神秘。对于下一个看到代码的开发人员来说,还有其他解决方案更有意义。将全局配置保存在模块中是一种常见的 ruby​​ 模式。另外:虽然这个特定的用例可能是安全的,但 YAML 是黑客的常见攻击媒介。最好不要养成使用它的习惯。如果需要配置文件,还有更多良性数据格式。
      • 神秘?我的同事非程序员经常更新这些参数,但他们会害怕更新模块,编写代码而不是配置文件,我敢打赌 yaml 更多地用作常见的 Ruby 模式,而不是使用模块进行配置,但当然所有这些都是自以为是的两个都可以用,谢谢评论
      【解决方案3】:

      您可以使用 Ruby 的 Singleton 模块,并创建一个类来包装 Statsd 的实例,以便在您的应用程序中使用。

      require "statsd-ruby"
      require "singleton"
      
      class MyStatsd
          attr_accessor :statsd
          include Singleton
          def initialize
              @statsd = Statsd.new 'localhost', 8125
          end
      end
      
      p MyStatsd.instance.statsd
      #=> #<Statsd:0x0000000281f180 @host="localhost", @port=8125,...
      

      注意: instance 方法将在第一次调用时构造对象,但是,它不接受任何参数,因此,我们不能将参数传递给 Statsd 的构造函数 - 因此必须很难在 MyStatsd 的构造函数中对值 localhost8125 进行编码 - 您可能必须找到另一种方法从 YAML 配置中获取这些值或使您的代码具有通用性。

      【讨论】:

        猜你喜欢
        • 2014-09-14
        • 2011-01-22
        • 2014-10-31
        • 1970-01-01
        • 1970-01-01
        • 2011-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多