Search code examples
rubymoney-rails

How could I remove duplicated sections in Ruby DSL


My current config format seems so redundant. How could I convert it into the next expected config format?

My expected config is:

MoneyRails.configure do |config|

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

My current config is:

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

Solution

  • 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
    

    The merge method merges two Hash instances and returns an Hash object. If the second Hash object has some keys matching the first then the second Hash's key => value replaces/overrides the former one.