From 191ffc94568ca22885eac7001cae7fef452dcfdd Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Fri, 15 Feb 2008 23:33:43 +0000 Subject: Serialize BigDecimals as Floats when using to_yaml. Closes #8746 [ernesto.jimenez] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8877 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activesupport/CHANGELOG | 2 ++ .../core_ext/bigdecimal/conversions.rb | 23 ++++++++++++++++++++++ activesupport/test/core_ext/bigdecimal.rb | 9 +++++++++ 3 files changed, 34 insertions(+) create mode 100644 activesupport/test/core_ext/bigdecimal.rb (limited to 'activesupport') diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 334772d947..468285ec43 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Serialize BigDecimals as Floats when using to_yaml. #8746 [ernesto.jimenez] + * Adding TimeWithZone #to_yaml, #to_datetime, #eql? and method aliases for duck-typing compatibility with Time [Geoff Buesing] * TimeWithZone #in_time_zone returns +self+ if zone argument is the same as #time_zone [Geoff Buesing] diff --git a/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb b/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb index dcdb08aea0..d2504302cd 100644 --- a/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb +++ b/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb @@ -1,6 +1,29 @@ +require 'yaml' + class BigDecimal #:nodoc: alias :_original_to_s :to_s def to_s(format="F") _original_to_s(format) end + + yaml_as "tag:yaml.org,2002:float" + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + # This emits the number without any scientific notation. + # I prefer it to using self.to_f.to_s, which would lose precision. + # + # Note that YAML allows that when reconsituting floats + # to native types, some precision may get lost. + # There is no full precision real YAML tag that I am aware of. + str = self.to_s + if str == "Infinity" + str = ".Inf" + elsif str == "-Infinity" + str = "-.Inf" + elsif str == "NaN" + str = ".NaN" + end + out.scalar( "tag:yaml.org,2002:float", str, :plain ) + end + end end diff --git a/activesupport/test/core_ext/bigdecimal.rb b/activesupport/test/core_ext/bigdecimal.rb new file mode 100644 index 0000000000..0417a2bca0 --- /dev/null +++ b/activesupport/test/core_ext/bigdecimal.rb @@ -0,0 +1,9 @@ +require 'abstract_unit' + +class BigDecimalTest < Test::Unit::TestCase + def test_to_yaml + assert_equal("--- 100000.30020320320000000000000000000000000000001\n", BigDecimal.new('100000.30020320320000000000000000000000000000001').to_yaml) + assert_equal("--- .Inf\n", BigDecimal.new('Infinity').to_yaml) + assert_equal("--- .NaN\n", BigDecimal.new('NaN').to_yaml) + end +end \ No newline at end of file -- cgit v1.2.3