【问题标题】:Ruby Configuration: replacing nested key value for dev environment doesn't workRuby 配置:替换开发环境的嵌套键值不起作用
【发布时间】:2012-12-21 18:40:42
【问题描述】:

案例:开发环境日志级别为 DEBUG 而生产环境日志级别为 INFO。如果环境 == 开发,我想使用每个默认日志配置并仅覆盖级别。

问题:可以覆盖第一级配置,但不能覆盖子级别。

考虑示例代码:

#file: config.rb

default = Configuration.for('default'){
  log {
    file '/tmp/foo.log'
    level 'WARN'
    freq 'daily'
  }
}

development = Configuration.for( 'development', default) {
  log {
    level 'DEBUG'
  }
}

在主文件中,我像这样使用上面的代码

# main.rb

require 'config.rb'    
$CONFIG = Configuration.for $DEV_ENV # either ('default' || 'development')
p $CONFIG.log.freq

我得到一个方法丢失错误:

`undefined method `freq' for #<Configuration:0x00000003a65d80> (NoMethodError)`

我唯一(丑陋的)解决方案是将文件和频率值恢复为默认值,如下所示:

  log {
    file default.log.file
    level 'DEBUG'
    freq default.log.freq
  }

哇哇哇!!可恶的!

还有其他建议吗?我也尝试用 SettingsLogic 和 Configatron 实现类似的东西,但无济于事。这里有 Ruby 的三个顶级配置 gem。我需要自己做吗??这真的是一个奇特的例子吗?

希望得到您的反馈或建议。

【问题讨论】:

  • 我想我可以像 log_level、log_file、log_freq 这样的东西都在第一个节点下。还是不好看。
  • 如果我想象 Configuration 调用该块,我得到undefined method 'log' for main:Object 并且我对您的错误并不感到惊讶。如果$CONFIG.log返回一个Configuration的实例,说明log已经被显式定义或者被method_missing定义为Configuration的实例方法。所有的魔法都可能发生在配置中,你应该展示它,以便我们可以看到发生了什么。
  • 配置不是我的课。它是下载次数排名第一的 ruby​​ 配置工具。 :)
  • 似乎无法访问内部默认数据。第二个日志覆盖第一个(使用 -w 选项运行 ruby​​)。另见stackoverflow.com/questions/8594433/…。没有好的答案。
  • 我不使用哈希的原因(此时我应该)是我从一个 YAML 类型的配置文件(Settingslogic)开始的。这样您就不需要程序员来配置应用程序。如果所有公司范围的应用程序的配置文件格式都相同,则它们是一致的。

标签: ruby configuration configatron settingslogic


【解决方案1】:

我能够使用 YAML 中的 SettingsLogic 和锚标签解决您的问题。

我的配置文件:

defaults: &defaults
  log: &logdefault
      file:  /tmp/foo.log
      level: WARN
      freq: daily

development:
  <<: *defaults
  log:
      <<: *logdefault
      level: DEBUG

test:
  <<: *defaults

production:
  <<: *defaults

诀窍是将默认值存储在锚标签中并在您尝试重新定义其中的一部分时重新使用它。每个级别都需要一个锚点。

你可以把它当作

require 'settingslogic'  #https://github.com/settingslogic/settingslogic
class SettingsDEV < Settingslogic
  source "./application.yml"
  namespace 'development'
end
p SettingsDEV.log #{"file"=>"/tmp/foo.log", "level"=>"DEBUG", "freq"=>"daily"}

class SettingsProd < Settingslogic
  source "./application.yml"
  namespace 'production'
end
p SettingsProd.log  #{"file"=>"/tmp/foo.log", "level"=>"WARN", "freq"=>"daily"}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 2014-06-16
    • 2014-03-11
    • 1970-01-01
    • 2016-07-14
    相关资源
    最近更新 更多