-
Notifications
You must be signed in to change notification settings - Fork 21.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unify behavior of all Numeric extensions and use Module.prepend inste…
…ad of alias_method
- Loading branch information
Showing
3 changed files
with
129 additions
and
152 deletions.
There are no files selected for viewing
15 changes: 7 additions & 8 deletions
15
activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,14 @@ | ||
require 'bigdecimal' | ||
require 'bigdecimal/util' | ||
|
||
class BigDecimal | ||
DEFAULT_STRING_FORMAT = 'F' | ||
alias_method :to_default_s, :to_s | ||
module ActiveSupport | ||
module BigDecimalWithDefaultFormat #:nodoc: | ||
DEFAULT_STRING_FORMAT = 'F' | ||
|
||
def to_s(format = nil, options = nil) | ||
if format.is_a?(Symbol) | ||
to_formatted_s(format, options || {}) | ||
else | ||
to_default_s(format || DEFAULT_STRING_FORMAT) | ||
def to_s(format = nil) | ||
super(format || DEFAULT_STRING_FORMAT) | ||
end | ||
end | ||
end | ||
|
||
BigDecimal.prepend(ActiveSupport::BigDecimalWithDefaultFormat) |
252 changes: 119 additions & 133 deletions
252
activesupport/lib/active_support/core_ext/numeric/conversions.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,145 +1,131 @@ | ||
require 'active_support/core_ext/big_decimal/conversions' | ||
require 'active_support/number_helper' | ||
|
||
class Numeric | ||
module ActiveSupport | ||
module NumericWithFormat | ||
|
||
# Provides options for converting numbers into formatted strings. | ||
# Options are provided for phone numbers, currency, percentage, | ||
# precision, positional notation, file size and pretty printing. | ||
# | ||
# ==== Options | ||
# | ||
# For details on which formats use which options, see ActiveSupport::NumberHelper | ||
# | ||
# ==== Examples | ||
# | ||
# Phone Numbers: | ||
# 5551234.to_s(:phone) # => 555-1234 | ||
# 1235551234.to_s(:phone) # => 123-555-1234 | ||
# 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234 | ||
# 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234 | ||
# 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555 | ||
# 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234 | ||
# 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.') | ||
# # => +1.123.555.1234 x 1343 | ||
# | ||
# Currency: | ||
# 1234567890.50.to_s(:currency) # => $1,234,567,890.50 | ||
# 1234567890.506.to_s(:currency) # => $1,234,567,890.51 | ||
# 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506 | ||
# 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51 € | ||
# -1234567890.50.to_s(:currency, negative_format: '(%u%n)') | ||
# # => ($1,234,567,890.50) | ||
# 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '') | ||
# # => £1234567890,50 | ||
# 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u') | ||
# # => 1234567890,50 £ | ||
# | ||
# Percentage: | ||
# 100.to_s(:percentage) # => 100.000% | ||
# 100.to_s(:percentage, precision: 0) # => 100% | ||
# 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000% | ||
# 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399% | ||
# 1000.to_s(:percentage, locale: :fr) # => 1 000,000% | ||
# 100.to_s(:percentage, format: '%n %') # => 100 % | ||
# | ||
# Delimited: | ||
# 12345678.to_s(:delimited) # => 12,345,678 | ||
# 12345678.05.to_s(:delimited) # => 12,345,678.05 | ||
# 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678 | ||
# 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678 | ||
# 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05 | ||
# 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05 | ||
# 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',') | ||
# # => 98 765 432,98 | ||
# | ||
# Rounded: | ||
# 111.2345.to_s(:rounded) # => 111.235 | ||
# 111.2345.to_s(:rounded, precision: 2) # => 111.23 | ||
# 13.to_s(:rounded, precision: 5) # => 13.00000 | ||
# 389.32314.to_s(:rounded, precision: 0) # => 389 | ||
# 111.2345.to_s(:rounded, significant: true) # => 111 | ||
# 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100 | ||
# 13.to_s(:rounded, precision: 5, significant: true) # => 13.000 | ||
# 111.234.to_s(:rounded, locale: :fr) # => 111,234 | ||
# 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true) | ||
# # => 13 | ||
# 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3 | ||
# 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.') | ||
# # => 1.111,23 | ||
# | ||
# Human-friendly size in Bytes: | ||
# 123.to_s(:human_size) # => 123 Bytes | ||
# 1234.to_s(:human_size) # => 1.21 KB | ||
# 12345.to_s(:human_size) # => 12.1 KB | ||
# 1234567.to_s(:human_size) # => 1.18 MB | ||
# 1234567890.to_s(:human_size) # => 1.15 GB | ||
# 1234567890123.to_s(:human_size) # => 1.12 TB | ||
# 1234567.to_s(:human_size, precision: 2) # => 1.2 MB | ||
# 483989.to_s(:human_size, precision: 2) # => 470 KB | ||
# 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB | ||
# 1234567890123.to_s(:human_size, precision: 5) # => "1.1229 TB" | ||
# 524288000.to_s(:human_size, precision: 5) # => "500 MB" | ||
# | ||
# Human-friendly format: | ||
# 123.to_s(:human) # => "123" | ||
# 1234.to_s(:human) # => "1.23 Thousand" | ||
# 12345.to_s(:human) # => "12.3 Thousand" | ||
# 1234567.to_s(:human) # => "1.23 Million" | ||
# 1234567890.to_s(:human) # => "1.23 Billion" | ||
# 1234567890123.to_s(:human) # => "1.23 Trillion" | ||
# 1234567890123456.to_s(:human) # => "1.23 Quadrillion" | ||
# 1234567890123456789.to_s(:human) # => "1230 Quadrillion" | ||
# 489939.to_s(:human, precision: 2) # => "490 Thousand" | ||
# 489939.to_s(:human, precision: 4) # => "489.9 Thousand" | ||
# 1234567.to_s(:human, precision: 4, | ||
# significant: false) # => "1.2346 Million" | ||
# 1234567.to_s(:human, precision: 1, | ||
# separator: ',', | ||
# significant: false) # => "1,2 Million" | ||
def to_formatted_s(format = :default, options = {}) | ||
case format | ||
when :phone | ||
return ActiveSupport::NumberHelper.number_to_phone(self, options) | ||
when :currency | ||
return ActiveSupport::NumberHelper.number_to_currency(self, options) | ||
when :percentage | ||
return ActiveSupport::NumberHelper.number_to_percentage(self, options) | ||
when :delimited | ||
return ActiveSupport::NumberHelper.number_to_delimited(self, options) | ||
when :rounded | ||
return ActiveSupport::NumberHelper.number_to_rounded(self, options) | ||
when :human | ||
return ActiveSupport::NumberHelper.number_to_human(self, options) | ||
when :human_size | ||
return ActiveSupport::NumberHelper.number_to_human_size(self, options) | ||
else | ||
self.to_default_s | ||
end | ||
end | ||
# Provides options for converting numbers into formatted strings. | ||
# Options are provided for phone numbers, currency, percentage, | ||
# precision, positional notation, file size and pretty printing. | ||
# | ||
# ==== Options | ||
# | ||
# For details on which formats use which options, see ActiveSupport::NumberHelper | ||
# | ||
# ==== Examples | ||
# | ||
# Phone Numbers: | ||
# 5551234.to_s(:phone) # => 555-1234 | ||
# 1235551234.to_s(:phone) # => 123-555-1234 | ||
# 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234 | ||
# 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234 | ||
# 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555 | ||
# 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234 | ||
# 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.') | ||
# # => +1.123.555.1234 x 1343 | ||
# | ||
# Currency: | ||
# 1234567890.50.to_s(:currency) # => $1,234,567,890.50 | ||
# 1234567890.506.to_s(:currency) # => $1,234,567,890.51 | ||
# 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506 | ||
# 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51 € | ||
# -1234567890.50.to_s(:currency, negative_format: '(%u%n)') | ||
# # => ($1,234,567,890.50) | ||
# 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '') | ||
# # => £1234567890,50 | ||
# 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u') | ||
# # => 1234567890,50 £ | ||
# | ||
# Percentage: | ||
# 100.to_s(:percentage) # => 100.000% | ||
# 100.to_s(:percentage, precision: 0) # => 100% | ||
# 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000% | ||
# 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399% | ||
# 1000.to_s(:percentage, locale: :fr) # => 1 000,000% | ||
# 100.to_s(:percentage, format: '%n %') # => 100 % | ||
# | ||
# Delimited: | ||
# 12345678.to_s(:delimited) # => 12,345,678 | ||
# 12345678.05.to_s(:delimited) # => 12,345,678.05 | ||
# 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678 | ||
# 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678 | ||
# 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05 | ||
# 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05 | ||
# 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',') | ||
# # => 98 765 432,98 | ||
# | ||
# Rounded: | ||
# 111.2345.to_s(:rounded) # => 111.235 | ||
# 111.2345.to_s(:rounded, precision: 2) # => 111.23 | ||
# 13.to_s(:rounded, precision: 5) # => 13.00000 | ||
# 389.32314.to_s(:rounded, precision: 0) # => 389 | ||
# 111.2345.to_s(:rounded, significant: true) # => 111 | ||
# 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100 | ||
# 13.to_s(:rounded, precision: 5, significant: true) # => 13.000 | ||
# 111.234.to_s(:rounded, locale: :fr) # => 111,234 | ||
# 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true) | ||
# # => 13 | ||
# 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3 | ||
# 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.') | ||
# # => 1.111,23 | ||
# | ||
# Human-friendly size in Bytes: | ||
# 123.to_s(:human_size) # => 123 Bytes | ||
# 1234.to_s(:human_size) # => 1.21 KB | ||
# 12345.to_s(:human_size) # => 12.1 KB | ||
# 1234567.to_s(:human_size) # => 1.18 MB | ||
# 1234567890.to_s(:human_size) # => 1.15 GB | ||
# 1234567890123.to_s(:human_size) # => 1.12 TB | ||
# 1234567.to_s(:human_size, precision: 2) # => 1.2 MB | ||
# 483989.to_s(:human_size, precision: 2) # => 470 KB | ||
# 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB | ||
# 1234567890123.to_s(:human_size, precision: 5) # => "1.1229 TB" | ||
# 524288000.to_s(:human_size, precision: 5) # => "500 MB" | ||
# | ||
# Human-friendly format: | ||
# 123.to_s(:human) # => "123" | ||
# 1234.to_s(:human) # => "1.23 Thousand" | ||
# 12345.to_s(:human) # => "12.3 Thousand" | ||
# 1234567.to_s(:human) # => "1.23 Million" | ||
# 1234567890.to_s(:human) # => "1.23 Billion" | ||
# 1234567890123.to_s(:human) # => "1.23 Trillion" | ||
# 1234567890123456.to_s(:human) # => "1.23 Quadrillion" | ||
# 1234567890123456789.to_s(:human) # => "1230 Quadrillion" | ||
# 489939.to_s(:human, precision: 2) # => "490 Thousand" | ||
# 489939.to_s(:human, precision: 4) # => "489.9 Thousand" | ||
# 1234567.to_s(:human, precision: 4, | ||
# significant: false) # => "1.2346 Million" | ||
# 1234567.to_s(:human, precision: 1, | ||
# separator: ',', | ||
# significant: false) # => "1,2 Million" | ||
def to_s(*args) | ||
return super unless args.first.is_a?(Symbol) | ||
|
||
[Fixnum, Bignum].each do |klass| | ||
klass.class_eval do | ||
alias_method :to_default_s, :to_s | ||
def to_s(base_or_format = 10, options = nil) | ||
if base_or_format.is_a?(Symbol) | ||
to_formatted_s(base_or_format, options || {}) | ||
else | ||
to_default_s(base_or_format) | ||
end | ||
end | ||
end | ||
end | ||
format, options = args | ||
options ||= {} | ||
|
||
Float.class_eval do | ||
alias_method :to_default_s, :to_s | ||
def to_s(*args) | ||
if args.empty? | ||
to_default_s | ||
case format | ||
when :phone | ||
return ActiveSupport::NumberHelper.number_to_phone(self, options) | ||
when :currency | ||
return ActiveSupport::NumberHelper.number_to_currency(self, options) | ||
when :percentage | ||
return ActiveSupport::NumberHelper.number_to_percentage(self, options) | ||
when :delimited | ||
return ActiveSupport::NumberHelper.number_to_delimited(self, options) | ||
when :rounded | ||
return ActiveSupport::NumberHelper.number_to_rounded(self, options) | ||
when :human | ||
return ActiveSupport::NumberHelper.number_to_human(self, options) | ||
when :human_size | ||
return ActiveSupport::NumberHelper.number_to_human_size(self, options) | ||
else | ||
to_formatted_s(*args) | ||
super | ||
end | ||
end | ||
end | ||
end | ||
|
||
[Fixnum, Bignum, Float, BigDecimal].each do |klass| | ||
klass.prepend(ActiveSupport::NumericWithFormat) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters