aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Koziarski <michael@koziarski.com>2008-02-15 23:33:43 +0000
committerMichael Koziarski <michael@koziarski.com>2008-02-15 23:33:43 +0000
commit191ffc94568ca22885eac7001cae7fef452dcfdd (patch)
tree7f8e307d7a343fc6d3ad31896028c3e8af1f8c31
parent3028ca59559d4c39412cdb8e4211ac6e1bded413 (diff)
downloadrails-191ffc94568ca22885eac7001cae7fef452dcfdd.tar.gz
rails-191ffc94568ca22885eac7001cae7fef452dcfdd.tar.bz2
rails-191ffc94568ca22885eac7001cae7fef452dcfdd.zip
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
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb23
-rw-r--r--activesupport/test/core_ext/bigdecimal.rb9
3 files changed, 34 insertions, 0 deletions
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