human_number 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7acf2929c3de8758cfbf05e32ec42a46c87ae2afb582f6fbbf0aeb8bcf6f9ede
4
+ data.tar.gz: 2ef9d5f7c7381ab0f13e1b4ec6936a9c55c16762fd87090a51810c1c7b6054af
5
+ SHA512:
6
+ metadata.gz: db81f31340cffd25a57aaaa6ecfe465231342c7cdefc420c37aa6855b23fe34abe4e06fddce0d5d1b0fd453115b01fb5a1718fdc0a54340c713e860bd4a2ae80
7
+ data.tar.gz: 2030078ab34f98cac34b8588c20cd240f9065f2be0dcfaf4d750e8123d4d232fcdc8b9fdac1588d8f3bbc5344b13bc4f4b4cdb7965b69c387cec1fef9c5e8bf5
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,63 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+ Exclude:
6
+ - 'vendor/**/*'
7
+ - 'bin/**/*'
8
+ - 'tmp/**/*'
9
+ - 'db/schema.rb'
10
+ - 'node_modules/**/*'
11
+
12
+ # Layout and formatting
13
+ Layout/LineLength:
14
+ Max: 120
15
+ AllowedPatterns:
16
+ - '\A\s*#.*\z' # Allow long comments
17
+
18
+ Layout/MultilineMethodCallIndentation:
19
+ EnforcedStyle: indented
20
+
21
+ # Style preferences for open source
22
+ Style/Documentation:
23
+ Enabled: false
24
+
25
+ Style/StringLiterals:
26
+ EnforcedStyle: double_quotes
27
+
28
+ Style/StringLiteralsInInterpolation:
29
+ EnforcedStyle: double_quotes
30
+
31
+ Style/HashSyntax:
32
+ EnforcedStyle: ruby19
33
+
34
+ Style/TrailingCommaInArrayLiteral:
35
+ EnforcedStyleForMultiline: consistent_comma
36
+
37
+ Style/TrailingCommaInHashLiteral:
38
+ EnforcedStyleForMultiline: consistent_comma
39
+
40
+ Style/FrozenStringLiteralComment:
41
+ Enabled: true
42
+ EnforcedStyle: always
43
+
44
+ # Metrics
45
+ Metrics/BlockLength:
46
+ Exclude:
47
+ - 'spec/**/*'
48
+ - '*.gemspec'
49
+ - 'Rakefile'
50
+
51
+ Metrics/ModuleLength:
52
+ Max: 300
53
+
54
+ Metrics/ClassLength:
55
+ Max: 300
56
+
57
+ Metrics/MethodLength:
58
+ Max: 20
59
+
60
+ Metrics/ParameterLists:
61
+ Max: 6
62
+
63
+ # RSpec rules removed - using basic RuboCop only
data/CHANGELOG.md ADDED
@@ -0,0 +1,90 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2024-01-31
9
+
10
+ ### Added
11
+
12
+ #### Core Number Formatting
13
+ - **Human-readable number formatting** with intelligent, culturally-appropriate abbreviations
14
+ - **Three cultural number systems** automatically selected by locale:
15
+ - **Western System**: K/M/B/T (thousand/million/billion/trillion) for English, German, French, Spanish, Italian, Portuguese, Russian, Dutch, Swedish, Danish, Norwegian
16
+ - **East Asian System**: 천/만/억/조 (Korean) and 千/万/億/兆 (Japanese/Chinese) for ko, ja, zh, zh-CN, zh-TW locales
17
+ - **Indian System**: thousand/lakh/crore for Hindi, Urdu, Bengali, and Indian English (hi, ur, bn, en-IN)
18
+
19
+ #### Currency Formatting
20
+ - **ISO 4217 currency code support** with native locale precision rules
21
+ - **Cross-locale consistency**: USD always shows 2 decimals, JPY shows 0, regardless of display locale
22
+ - **40+ currency mappings** with native locale associations for accurate formatting
23
+ - **Human-readable currency formatting** combining cultural abbreviations with currency symbols
24
+
25
+ #### API Methods
26
+ - `HumanNumber.human_number(number, **options)` - Formats numbers with cultural abbreviations
27
+ - `HumanNumber.currency(number, currency_code:, locale:)` - Standard currency formatting
28
+ - `HumanNumber.human_currency(number, currency_code:, locale:, **options)` - Currency with abbreviations
29
+
30
+ #### Formatting Options
31
+ - **Precision control**: `max_digits` parameter for significant digit control (1-4 digits or nil for complete mode)
32
+ - **Unit preferences**: `abbr_units` to choose between abbreviated (K/M) vs full words (thousand/million)
33
+ - **Minimum thresholds**: `min_unit` to prevent abbreviation below specified amounts
34
+ - **Zero trimming**: `trim_zeros` to control trailing decimal zero display
35
+ - **Complete mode**: `max_digits: nil` shows full breakdown across multiple units (e.g., "1M 234K 567")
36
+
37
+ #### Rails Integration
38
+ - **Automatic Rails detection** and helper loading via Railtie
39
+ - **View helpers**: `human_number`, `currency`, `human_currency` with Rails-friendly parameter handling
40
+ - **I18n integration**: Automatic locale detection from `I18n.locale`
41
+ - **Legacy compatibility**: `number_to_human_size` alias for backward compatibility
42
+
43
+ #### Locale Data System
44
+ - **Hybrid locale approach**: Combines rails-i18n for base formatting with custom locale files for unit symbols
45
+ - **14 custom locale files**: bn, de, en-GB, en-IN, en, es, fr, hi, ja, ko, ur, zh-CN, zh-TW, zh
46
+ - **Rails-i18n structure**: `number.human.decimal_units.units` for unit translations
47
+ - **Automatic locale file loading** from `config/locales/` directory
48
+
49
+ #### Architecture & Performance
50
+ - **Configuration-free design**: No global state, explicit parameters for predictable behavior
51
+ - **Direct class methods**: Zero object instantiation overhead for optimal performance
52
+ - **Thread-safe implementation**: No shared mutable state between calls
53
+ - **Two-stage formatting**: Clean separation between number formatting and currency application
54
+ - **Efficient I18n**: Leverages Rails I18n caching mechanisms
55
+
56
+ #### Standards Compliance
57
+ - **Microsoft Globalization documentation** compliance for cultural number formatting
58
+ - **Unicode CLDR standards** for locale-specific formatting rules
59
+ - **ISO 4217 standard** for currency codes and precision rules
60
+ - **rails-i18n integration** for verified locale data
61
+
62
+ #### Development Infrastructure
63
+ - **Comprehensive test suite**: 106 test examples with 100% code coverage
64
+ - **RuboCop compliance**: Complete adherence to Ruby style guidelines
65
+ - **Rake tasks**: Integrated testing and linting workflow
66
+ - **Gem packaging**: Ready for RubyGems distribution
67
+
68
+ #### Dependencies
69
+ - **Runtime dependencies**: `actionview` (>= 5.2), `i18n` (>= 1.6, < 2), `rails-i18n` (>= 5.1)
70
+ - **Ruby requirement**: >= 3.1.0
71
+ - **Development dependencies**: `rspec`, `rubocop`, `simplecov`, `yard`
72
+
73
+ ### Technical Details
74
+
75
+ #### Number System Architecture
76
+ - **DefaultSystem**: Handles Western locales with standard thousand/million/billion/trillion units
77
+ - **EastAsianSystem**: Implements East Asian counting with ten-thousand (만/万) and hundred-million (억/億) bases
78
+ - **IndianSystem**: Supports Indian numbering with lakh (100,000) and crore (10,000,000) units
79
+
80
+ #### Currency Precision System
81
+ - **LocaleSupport module**: Centralized currency-to-locale mapping for consistent precision
82
+ - **Native locale detection**: Automatic selection of appropriate formatting locale for each currency
83
+ - **Precision inheritance**: Currency formatting inherits precision rules from native locales
84
+
85
+ #### Formatter Pattern
86
+ - **Formatters::Number**: Core number formatting with intelligent unit system selection
87
+ - **Formatters::Currency**: Currency symbol and format string application
88
+ - **Clean separation**: Number formatting independent of currency concerns
89
+
90
+ [0.1.0]: https://github.com/yourusername/human_number/releases/tag/v0.1.0
data/CLAUDE.md ADDED
@@ -0,0 +1,219 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ HumanNumber is a Ruby gem that implements accurate number formatting based on international standards (Microsoft Globalization and Unicode CLDR). It provides human-readable number formats with precise locale-specific formatting rules for basic numbers, currency, and large number simplification.
8
+
9
+ ### Key Features
10
+ - International standards-compliant number formatting
11
+ - Currency formatting with ISO 4217 support
12
+ - Large number simplification with cultural variations (K/M/B vs 千/万/億/兆)
13
+ - Rails integration via helpers and Railtie
14
+ - Built on rails-i18n for locale data
15
+
16
+ ## Development Commands
17
+
18
+ ### Testing
19
+ ```bash
20
+ # Run all tests
21
+ rake spec
22
+ # or
23
+ bundle exec rspec
24
+
25
+ # Run a specific test file
26
+ bundle exec rspec spec/human_number_spec.rb
27
+
28
+ # Run a specific test
29
+ bundle exec rspec spec/human_number_spec.rb:line_number
30
+ ```
31
+
32
+ ### Code Quality
33
+ ```bash
34
+ # Run RuboCop linting
35
+ rake rubocop
36
+ # or
37
+ bundle exec rubocop
38
+
39
+ # Auto-fix RuboCop issues
40
+ bundle exec rubocop -a
41
+ ```
42
+
43
+ ### Default Development Task
44
+ ```bash
45
+ # Runs both tests and linting
46
+ rake
47
+ ```
48
+
49
+ ### Gem Management
50
+ ```bash
51
+ # Build the gem
52
+ rake build
53
+
54
+ # Install locally
55
+ rake install
56
+
57
+ # Release (requires proper credentials)
58
+ rake release
59
+ ```
60
+
61
+ ## Architecture
62
+
63
+ ### Core Module Structure
64
+ The gem follows a modular formatter pattern:
65
+
66
+ - **`HumanNumber`** (main module): Provides public API methods (`human_number`, `currency`, `human_currency`) and configuration
67
+ - **`HumanNumber::Formatters::Number`**: Handles number formatting with intelligent unit system selection
68
+ - **`HumanNumber::Formatters::Currency`**: Applies currency symbols and format strings to formatted numbers
69
+ - **Number System Classes**: `DefaultSystem`, `EastAsianSystem`, `IndianSystem` - each implements locale-specific unit systems
70
+
71
+ ### Two-Stage Formatting Process
72
+ The gem uses a clear separation between number formatting and currency application:
73
+
74
+ 1. **Number Formatting**: Converts numbers to human-readable strings with cultural units
75
+ 2. **Currency Application**: Applies currency symbols and format strings
76
+
77
+ ```ruby
78
+ # Internal flow for HumanNumber.human_currency(1234567, currency_code: 'USD', locale: :en)
79
+ formatted_number = Formatters::Number.format(1234567, locale: :en, max_digits: 2) #=> "1.2M"
80
+ final_result = Formatters::Currency.format("1.2M", currency_code: 'USD', locale: :en) #=> "$1.2M"
81
+ ```
82
+
83
+ ### Cultural Number System Architecture
84
+ The gem automatically selects appropriate number systems based on locale:
85
+
86
+ - **Western System** (`DefaultSystem`): K/M/B/T (thousand/million/billion/trillion)
87
+ - Used by: English, German, French, Spanish, Italian, Portuguese, Russian, Dutch, Swedish, Danish, Norwegian
88
+ - Target locales: `%i[en es fr de it pt ru nl sv da no]`
89
+
90
+ - **East Asian System** (`EastAsianSystem`): 천/만/억/조 or 千/万/億/兆
91
+ - Used by: Korean, Japanese, Chinese
92
+ - Target locales: `%i[ko ja zh zh-CN zh-TW]`
93
+ - Units: 천/千 (thousand), 만/万 (ten thousand), 억/億 (hundred million), 조/兆 (trillion)
94
+
95
+ - **Indian System** (`IndianSystem`): thousand/lakh/crore
96
+ - Used by: Hindi, Urdu, Bengali, Indian English
97
+ - Target locales: `%i[hi ur bn en-IN]`
98
+ - Units: thousand (1,000), lakh (100,000), crore (10,000,000)
99
+
100
+ ### Locale Data Integration
101
+ The gem uses a hybrid approach combining rails-i18n with custom locale files:
102
+ - Uses `I18n.t("number.format.delimiter")` and `I18n.t("number.format.separator")` for basic number formatting (from rails-i18n)
103
+ - Uses `I18n.t("number.currency.format.*")` for currency formatting (from rails-i18n)
104
+ - Uses `I18n.t("number.human.decimal_units.units.*")` for large number unit symbols (from custom locale files in `config/locales/`)
105
+ - Custom locale files follow rails-i18n structure: `number.human.decimal_units.units`
106
+ - Validates locales against `I18n.available_locales`
107
+ - Railtie automatically loads custom locale files from `config/locales/` directory
108
+
109
+ ### Currency-Locale Mapping System
110
+ `HumanNumber::LocaleSupport` provides centralized currency precision logic:
111
+
112
+ ```ruby
113
+ CURRENCY_NATIVE_LOCALES = {
114
+ "USD" => [:en], "EUR" => %i[de fr es it nl],
115
+ "KRW" => [:ko], "JPY" => [:ja]
116
+ # ... 40+ currencies
117
+ }
118
+ ```
119
+
120
+ This ensures:
121
+ - **Consistent precision rules**: USD always shows 2 decimals, JPY shows 0
122
+ - **Smart fallbacks**: When user locale doesn't match currency's native locale
123
+ - **Easy maintenance**: New currencies require only one mapping entry
124
+
125
+ ### Rails Integration
126
+ - **`HumanNumber::Railtie`**: Automatically loads Rails helpers when Rails is present
127
+ - **`HumanNumber::Rails::Helpers`**: Provides view/controller helper methods (`human_number`, `currency`, `human_currency`)
128
+ - Rails helpers default to `I18n.locale` and provide Rails-friendly parameter handling
129
+
130
+ ### Dependencies
131
+ - **Runtime**: `i18n`, `rails-i18n`, `actionview`
132
+ - **Development**: `rspec`, `rubocop`, `simplecov`, `yard`
133
+ - **Rails Integration**: Optional Rails dependency for helper integration
134
+
135
+ ## Configuration-Free Design Philosophy
136
+
137
+ HumanNumber deliberately avoids runtime configuration in favor of explicit parameters:
138
+
139
+ ```ruby
140
+ # No global configuration
141
+ HumanNumber.human_number(1234567, locale: :ko, max_digits: 2)
142
+
143
+ # Application defaults handled at application level
144
+ class ApplicationController
145
+ def format_money(amount, currency)
146
+ HumanNumber.human_currency(amount, currency_code: currency, locale: I18n.locale, max_digits: 2)
147
+ end
148
+ end
149
+ ```
150
+
151
+ **Benefits:**
152
+ - No shared state or thread safety concerns
153
+ - Predictable behavior (each call is independent)
154
+ - Easier testing (no configuration setup/teardown)
155
+ - Better performance (no configuration object overhead)
156
+
157
+ ## Testing Configuration
158
+
159
+ - Uses RSpec with documentation format output
160
+ - SimpleCov for test coverage
161
+ - Test setup resets I18n locale and HumanNumber configuration before each test
162
+ - Available locales configured for comprehensive locale testing
163
+
164
+ ## Adding New Features
165
+
166
+ ### Adding New Formatters
167
+ To add a new formatter type:
168
+ 1. Create new class in `lib/human_number/formatters/` inheriting from appropriate base
169
+ 2. Implement the required methods
170
+ 3. Add to main `HumanNumber` module with public method
171
+ 4. Update Rails helpers if appropriate
172
+ 5. Add comprehensive tests covering locale variations
173
+
174
+ ### Adding New Locales
175
+ To add support for a new locale:
176
+ 1. Create new YAML file in `config/locales/` (e.g., `fr.yml`)
177
+ 2. Follow rails-i18n structure: `number.human.decimal_units.units`
178
+ 3. Define appropriate unit symbols for the locale
179
+ 4. Consider cultural number unit systems (Western vs Asian patterns)
180
+ 5. Add tests for the new locale in the test suite
181
+
182
+ ### Adding New Number Systems
183
+ To add a new cultural number system:
184
+ 1. Create new system class in `Formatters::Number` (e.g., `ArabicSystem`)
185
+ 2. Define `TARGET_LOCALES` and `UNIT_DEFINITIONS` constants
186
+ 3. Implement `format_number` class method
187
+ 4. Add to `determine_system_class` method in `Formatters::Number`
188
+ 5. Add locale files for the new system's locales
189
+ 6. Add comprehensive test coverage
190
+
191
+ Example locale file structure:
192
+ ```yaml
193
+ fr:
194
+ number:
195
+ human:
196
+ decimal_units:
197
+ abbr_units:
198
+ thousand: "k"
199
+ million: "M"
200
+ billion: "Md"
201
+ trillion: "Bn"
202
+ ```
203
+
204
+ ## Performance Considerations
205
+
206
+ - **Zero Allocation**: Direct class methods avoid object instantiation
207
+ - **Thread Safe**: No shared mutable state between calls
208
+ - **Efficient I18n**: Leverages Rails I18n caching mechanisms
209
+ - **Smart Defaults**: Optimized for common use cases
210
+ - **System Class Delegation**: Efficient dispatch to appropriate number system
211
+
212
+ ## Standards Reference
213
+
214
+ This project is based on the following international standards:
215
+ - [Microsoft Globalization - Number Formatting](https://learn.microsoft.com/en-us/globalization/locale/number-formatting)
216
+ - [Microsoft Globalization - Currency Formats](https://learn.microsoft.com/en-us/globalization/locale/currency-formats)
217
+ - [Unicode CLDR](http://cldr.unicode.org/)
218
+ - [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)
219
+ - [rails-i18n](https://github.com/svenfuchs/rails-i18n)
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Ruby version requirement (matches gemspec)
6
+ ruby ">= 3.1.0"
7
+
8
+ # Specify your gem's dependencies in human_number.gemspec
9
+ gemspec
10
+
11
+ group :development do
12
+ gem "bundler", "~> 2.0"
13
+ gem "rake", "~> 13.0"
14
+ gem "rubocop", "~> 1.0"
15
+ gem "rubocop-rspec", "~> 2.0"
16
+ gem "yard", "~> 0.9"
17
+ end
18
+
19
+ group :test do
20
+ gem "rspec", "~> 3.0"
21
+ gem "rspec-rails", "~> 5.0"
22
+ gem "simplecov", "~> 0.21", require: false
23
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Your Name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.