RubyMoney/money
74.9
Strong · 19 September 2026
2.5k
lines of production code
Ruby
primary language
1
measurement over time
What this system is
This system is the Money gem, a Ruby library for handling monetary values and currency exchange. It provides core capabilities for creating, formatting, and performing arithmetic on money amounts using BigDecimal precision, alongside a modular architecture for currency conversion and locale-specific formatting. The library also includes thread-safe storage for exchange rates and supports static type checking via RBS signatures.
How it got here
2008–2010 — Major v7.0 rewrite and modularization
6 changes.
This period centered on a comprehensive rewrite of the Money library for version 7.0, shifting internal storage from integer cents to BigDecimal for infinite precision and introducing a modular architecture with distinct components for arithmetic, formatting, and currency management. The work involved significant API breaking changes, including the removal of legacy locale backends and deprecated methods, while establishing a new Currency class and refactoring the exchange bank system to support more flexible rate storage and handling.
2011–2018 — Modular refactoring and thread safety
5 changes.
The Money library underwent a significant structural refactoring, decomposing the core class into modular components for allocation, arithmetic, and formatting to improve maintainability. This period also introduced thread-safe exchange rate storage and a pluggable locale backend abstraction, while deprecating implicit currency heuristics in favor of explicit loading mechanisms.
2023–2025 — RBS type signature implementation
6 changes.
This period focused on adding comprehensive RBS type signatures for the Money library's core classes, including Money, Currency, Bank, and RatesStore, to enable static type checking and improved IDE support. The work also involved standardizing the test suite configuration and introducing Bundler binstubs to streamline the developer workflow.
Features
Add RBS type signatures for Money and Currency classes
This change introduces RBS type signature files (sig/lib/money/money.rbs and sig/lib/money/currency.rbs) for the Money and Money::Currency classes. These signatures define the public API, including attributes like \cents\, \fractional\, and \currency\, as well as methods for currency lookup, registration, and comparison. This enables static type checking and improved IDE support for developers using the Money library.
sig/lib/money · high confidence
Added RBS type signatures for Money::Bank and Currency::Heuristics
This change introduces RBS type signature files for the Money library's currency exchange and heuristic modules. It defines the interface for Money::Bank::Base, including error classes and the core exchange\_with method, as well as specific implementations like SingleCurrency (which prevents cross-currency exchanges) and VariableExchange (which handles rate storage and conversion). Additionally, it adds a signature for the deprecated Money::Currency::Heuristics module.
sig/lib/money/bank · high confidence
RBS type signatures for Money library
Added RBS type signature files for the Money library, including definitions for the Money class, its Allocation module (with configurable precision for splits), Arithmetic operations (including strict currency-aware equality checks), Constructors for various currencies, and the Formatter and LocaleBackend modules.
sig/lib/money/money · high confidence
Behavioural changes
Added Bundler binstubs for rake, rbs, rspec, and rubocop
The project now includes generated binstubs in the \bin/\ directory for rake, rbs, rspec, and rubocop. These scripts allow developers to run these tools directly (e.g., \./bin/rake\) without needing to prefix commands with \bundle exec\, simplifying the command-line workflow while ensuring the correct gem versions are loaded via Bundler.
bin · high confidence
Added type signatures for the in-memory exchange rate store
Introduced RBS type signatures for the \Money::RatesStore::Memory\ class, defining the interface for thread-safe storage of exchange rate pairs. This includes type definitions for initialization, adding and retrieving rates, iterating over stored rates, and internal transaction handling, enabling static type checking for applications using the in-memory rate store.
_sig/lib/money/rates\store · high confidence
Deprecation of built-in currency heuristics and introduction of explicit loader
The built-in currency identification heuristics have been removed from the core library; calling \Money::Currency.analyze\ now raises a deprecation error instructing users to add the \money-heuristics\ gem to their Gemfile. Additionally, currency loading has been refactored to use a dedicated \Money::Currency::Loader\ module that explicitly reads from JSON files in the config directory, replacing the previous implicit loading mechanism.
lib/money/currency · high confidence
Introduce Money::Bank::Base and new SingleCurrency bank
The currency exchange architecture has been refactored to include a new abstract base class, Money::Bank::Base, which defines the core interface for bank implementations (including a setup hook and rounding method) and a dedicated Money::Bank::SingleCurrency class that prevents cross-currency exchanges by raising an error. This change restructures the existing Money::Bank::VariableExchange to inherit from this new base, decoupling the rate storage logic into a separate Money::RatesStore::Memory component while maintaining the same public API for adding and exchanging rates.
lib/money/bank · high confidence
Introduce locale\_backend abstraction for currency formatting
The library now uses a pluggable \LocaleBackend\ abstraction to handle currency formatting lookups, replacing the previous direct implementation. This change introduces a \Base\ class and two concrete backends: \I18n\, which maps formatting keys (like \thousands\_separator\ and \symbol\) to I18n translation scopes, and \Currency\, which allows explicit per-currency localization via method calls. This structure enables more flexible and testable locale handling for money formatting.
_lib/money/locale\backend · high confidence
Major library rewrite: modular architecture, BigDecimal precision, and new Currency class
The Money library has been rewritten from version 6.x to 7.1.1, introducing a modular structure with separate modules for arithmetic, constructors, formatting, allocation, and locale backends. The internal storage for monetary amounts has shifted from Integer cents to BigDecimal to support infinite precision and avoid floating-point errors. A new Money::Currency class replaces the previous constant-based currency definitions, providing a singleton-based registry with support for inheritance, dynamic registration, and ISO 4217 numeric lookups. Currency exchange logic has been refactored into distinct bank implementations (VariableExchange and SingleCurrency) replacing the old NoExchangeBank and VariableExchangeBank. Core extensions for Numeric and String have been removed in favor of the Monetize gem. Users should note that methods like \#cents are now aliases for \#fractional, and formatting behavior has been standardized through a dedicated Formatter class.
lib/money · high confidence
Major version 7.0 release with breaking changes to defaults and API
This release introduces several breaking changes: the default currency is now \nil\ instead of \USD\ (requiring explicit currency specification or setting \Money.default\_currency\), the default rounding mode has shifted from \ROUND\_HALF\_EVEN\ to \ROUND\_HALF\_UP\, and the legacy locale backend has been removed in favor of a \:currency\ default backend. Deprecated methods such as \Money\#dollars\, \Money.infinite\_precision\, and \Money\#currency\_as\_string\ have been removed, along with deprecated formatting rules like \:html\ and \:symbol\_position\. The library now requires Ruby \>= 3.1 and i18n \~\> 1.9. Additionally, \Money::Currency.reset!\ now correctly clears cached keys, and importing JSON rates uses \JSON.parse\ instead of the unsafe \JSON.load\.
(repo-wide) · high confidence
Refactored Money class into modular components with updated comparison and formatting behavior
The Money class has been restructured into separate modules (Allocation, Arithmetic, Constructors, Formatter, FormattingRules, LocaleBackend) to improve maintainability. Key behavioral changes include: Money\#eql? now returns false for zero amounts in different currencies (with a deprecation warning for the old behavior); Money\#== raises an error when comparing with non-zero numeric values; comparison operators return nil for invalid cross-currency comparisons instead of raising errors; and the formatting system now uses a new Formatter class with updated rules supporting options like :format templates, :south\_asian\_number\_formatting, and :delimiter\_pattern. Constructor methods have been extracted to a dedicated module, and the locale backend abstraction now supports both i18n and currency-based backends.
lib/money/money · high confidence
Removes internal cattr\_accessor and adds standard library dependencies
The library no longer includes its own \cattr\_accessor\ helper, removing the \lib/support/cattr\_accessor.rb\ file and replacing it with standard Ruby features. Additionally, \lib/money.rb\ now explicitly requires \bigdecimal\, \set\, and \i18n\, ensuring these dependencies are loaded before the core Money class initializes.
lib · high confidence
Thread-safe exchange rate storage in Money::RatesStore::Memory
The library now includes a new \Money::RatesStore::Memory\ class that provides thread-safe storage for exchange rate pairs, replacing the previous internal storage mechanism in \Bank::VariableExchange\. This store uses a \Monitor\ to synchronize all data access (adding, retrieving, and iterating rates), ensuring safe concurrent usage. It also supports serialization via \marshal\_dump\, allowing the store's state to be safely saved and restored.
_lib/money/rates\store · high confidence
Test coverage
Added comprehensive test coverage for Money core components; Initial RSpec test suite for Money class; Test suite support files for RSpec configuration and warning suppression.
Dependencies
Initial gemspec and Gemfile setup for Money gem v6.13.3
This change introduces the foundational dependency manifests for the Money gem. The gemspec defines the library's core runtime dependencies on \bigdecimal\ and \i18n\ (version \~\> 1.9), sets the minimum required Ruby version to 3.1, and includes gem metadata for changelog and source code links. The Gemfile establishes the development environment, specifying test tools (RSpec \~\> 3.4, SimpleCov), linting suites (Rubocop and its extensions), and documentation generators (Yard, RDoc, Redcarpet).
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 75.
Lenses
- Code Health 97
- Architecture 100
- Maturity 64
- Readiness 74
- Security 92
Changes since last survey
- 300 commits — 240 feature/other, 60 fixes
By area
- (root) — 105 commits
- (repo) — 98 commits
- lib/money — 35 commits
- spec/money — 12 commits
- .github/workflows — 11 commits
- config/currency_iso.json — 11 commits
- spec/money_spec.rb — 10 commits
- sig/lib — 7 commits
- spec/bank — 4 commits
- .github/dependabot.yml — 1 commit
- lib/money.rb — 1 commit
- sig/manifest.yml — 1 commit
- spec/currency — 1 commit
- spec/currency_spec.rb — 1 commit
- spec/spec_helper.rb — 1 commit
- spec/support — 1 commit
Notable commits
- fix: Document ANG name fix in CHANGELOG
- fix: FIx doc comment error in formatter.rb
- fix: Fix HTTP links
- fix: Fix JRuby 10 CI failure by restricting rdoc to MRI (#1221)
- fix: Fix MGA (Malagasy Ariary) to be a zero-decimal currency
- fix: Fix Money::Currency.register exception when table is not initialized (#1173)
- fix: Fix O(n2) to be O(n)
- fix: Fix XPF currency symbol from 'Fr' to '₣'
- fix: Fix XPF currency symbol from 'Fr' to '₣' (#1205)
- fix: Fix and validate RBS signatures (#1222)
- fix: Fix implicit block expectation syntax warning
- fix: Fix name for ANG currency
- fix: Fix name for ANG currency (#1191)
- fix: Fix param type
- fix: Fix thousands separator for CHF
- fix: Fixes spec due to regression in df6525f3
- fix: Lint: Fix Layout/ArgumentAlignment (#1176)
- fix: Lint: Fix Layout/EndAlignment (#1177)
- fix: Lint: Fix Layout/LineLength (#1209)
- fix: Lint: Fix Lint cops (#1194)
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
RubyMoney/money was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 227f7366845f7204d75bb3b36e88cd1c708fda0b — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.