我怎么能删除Ruby DSL中的重复部分

时间:2015-11-01 13:51:51

标签: ruby money-rails

我当前的配置格式似乎很冗余。我怎么能把它转换成下一个预期的配置格式?

我的预期配置是:

MoneyRails.configure do |config|

    register_currency("TWD", 100)
    register_currency("USD", 100)
    ....
end

我当前的配置是:

MoneyRails.configure do |config|

  config.register_currency = {
    :priority            => 1,
    :iso_code            => "TWD",
    :name                => "TWD",
    :symbol              => "NT$ ",
    :symbol_first        => true,
    :subunit             => "Subcent",
    :subunit_to_unit     => 100,
    :thousands_separator => ",",
    :decimal_mark        => "."
  }

  config.register_currency = {
    :priority            => 1,
    :iso_code            => "USD",
    :name                => "USD",
    :symbol              => "$ ",
    :symbol_first        => true,
    :subunit             => "Subcent",
    :subunit_to_unit     => 100,
    :thousands_separator => ",",
    :decimal_mark        => "."
  }

  config.register_currency = {
    :priority            => 1,
    :iso_code            => "SGD",
    :name                => "SGD",
    :symbol              => "$ ",
    :symbol_first        => true,
    :subunit             => "Subcent",
    :subunit_to_unit     => 100,
    :thousands_separator => ",",
    :decimal_mark        => "."
  }

  config.register_currency = {
    :priority            => 1,
    :iso_code            => "THB",
    :name                => "THB",
    :symbol              => "$ ",
    :symbol_first        => true,
    :subunit             => "Subcent",
    :subunit_to_unit     => 100,
    :thousands_separator => ",",
    :decimal_mark        => "."
  }

  config.register_currency = {
    :priority            => 1,
    :iso_code            => "AUD",
    :name                => "AUD",
    :symbol              => "$ ",
    :symbol_first        => true,
    :subunit             => "Subcent",
    :subunit_to_unit     => 100,
    :thousands_separator => ",",
    :decimal_mark        => "."
  }

  config.register_currency = {
    :priority            => 1,
    :iso_code            => "KRW",
    :name                => "KRW",
    :symbol              => "$ ",
    :symbol_first        => true,
    :subunit             => "Subcent",
    :subunit_to_unit     => 100,
    :thousands_separator => ",",
    :decimal_mark        => "."
  }

  ...

end

3 个答案:

答案 0 :(得分:1)

创建这个小模块怎么样?您只需要在配置对象中添加一个额外的属性:

module MoneyRails
  module MyApp
    def register_currency(config, name, subunit_to_unit)
      config.register_currency(options_hash(name, subunit_to_unit))
    end

    private

    def options_hash(name, subunit_to_unit)
      {
        :priority            => 1,
        :iso_code            => name,
        :name                => name,
        :symbol              => "$ ",
        :symbol_first        => true,
        :subunit             => "Subcent",
        :subunit_to_unit     => subunit_to_unit,
        :thousands_separator => ",",
        :decimal_mark        => "."
      }
    end
  end
end

注意我命名它是为了不污染基本命名空间。改变你的闲暇。

然后:

include MoneyRails::MyApp

MoneyRails.configure do |config|

    register_currency(config, "TWD", 100)
    register_currency(config, "USD", 100)
    ....
end

答案 1 :(得分:1)

default_options = {
    :priority            => 1,
    :iso_code            => 'USD',
    :name                => 'USD',
    :symbol              => "$ ",
    :symbol_first        => true,
    :subunit             => "Subcent",
    :subunit_to_unit     => 100,
    :thousands_separator => ",",
    :decimal_mark        => "."
}

MoneyRails.configure do |config|
  config.register_currency = default_options
  config.register_currency = default_options.merge(name: 'TWD', iso_code: 'TWD', symbol: 'NT$')
  config.register_currency = default_options.merge(name: 'THB', iso_code: 'THB')
  config.register_currency = default_options.merge(name: 'SGD')
end

merge方法合并两个Hash实例并返回一个Hash对象。如果第二个Hash对象有一些与第一个匹配的键,则第二个Hash的key => value替换/覆盖前一个。

答案 2 :(得分:0)

相对较少的例外情况,因此我倾向于将这些例外与货币名称缩写一起放入文件中,每行一行。例如,一行可能是:

TWD SYM:"NT$ "

(或TWD SYM:NT$如果:symbol的所有值在末尾都有一个空格。)

大多数行只有货币缩写,例如:

USD

然后,您将读取该文件并将其解析为如下所示的数组:

specific_bits = [
  ["TWD", { symbol: "NT$ " }],
  ["USD", {}],
  ["SGD", {} ],
  ["THB", { subunit_to_unit: 999 }],
  ["AUD", {}],
  ["KRW", {}],
  ["XYZ", { symbol: "XT$ ", subunit_to_unit: -5 }],
]

然后定义:

BASE_HASH = {
  priority:            1,
  symbol:              "$ ",
  symbol_first:        true,
  subunit:             "Subcent",
  subunit_to_unit:     100,
  thousands_separator: ",",
  decimal_mark:        "."
}

这使您可以非常简单地构造哈希:

specific_bits.map do |name, exceptions|
  h = { :iso_code => name, :name => name }
  exceptions.each { |k,v| h[k] = v }
  BASE_HASH.merge h
end
  #=> [{:priority=>1, :symbol=>"NT$ ", :symbol_first=>true,    :subunit=>"Subcent",
  #    :subunit_to_unit=>100, :thousands_separator=>",", :decimal_mark=>".",
  #    :iso_code=>"TWD", :name=>"TWD"},
  #    {...
  #    ...]

如果您希望按键按特定顺序排列,那就是一个小调整。