Skip to content
Browse files

Serialize BigDecimals as Floats when using to_yaml. Closes #8746 [ern…

…esto.jimenez]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8877 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent 3028ca5 commit 191ffc94568ca22885eac7001cae7fef452dcfdd @NZKoz NZKoz committed Feb 15, 2008
View
2 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]
View
23 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
View
9 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

0 comments on commit 191ffc9

Please sign in to comment.
Something went wrong with that request. Please try again.