From 8ac8182fb797b7d1757cc6ca514ea98de5148096 Mon Sep 17 00:00:00 2001 From: Serge Balyuk Date: Fri, 4 Jun 2010 15:41:47 +0300 Subject: [PATCH] Fixed attr_accessor_with_default causing "singleton can't be dumped" TypeError on object marshaling [#4776 state:resolved] --- .../core_ext/module/attr_accessor_with_default.rb | 18 +++++++++++------- .../module/attr_accessor_with_default_test.rb | 11 +++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb b/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb index 28ac89d..1231628 100644 --- a/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb +++ b/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb @@ -20,12 +20,16 @@ class Module # def attr_accessor_with_default(sym, default = nil, &block) raise 'Default value or block required' unless !default.nil? || block - define_method(sym, block_given? ? block : Proc.new { default }) - module_eval(<<-EVAL, __FILE__, __LINE__ + 1) - def #{sym}=(value) # def age=(value) - class << self; attr_reader :#{sym} end # class << self; attr_reader :age end - @#{sym} = value # @age = value - end # end - EVAL + + attr_writer sym + + block = Proc.new { default } unless block_given? + define_method(sym) do + if instance_variable_defined?("@#{sym}") + instance_variable_get("@#{sym}") + else + instance_eval(&block) + end + end end end diff --git a/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb b/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb index 7c0d0bb..325fb51 100644 --- a/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb +++ b/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb @@ -8,8 +8,13 @@ class AttrAccessorWithDefaultTest < Test::Unit::TestCase 'helper' end end + self.class.const_set(:TestClass, @target) @instance = @target.new end + + def teardown + self.class.send(:remove_const, :TestClass) + end def test_default_arg @target.attr_accessor_with_default :foo, :bar @@ -28,4 +33,10 @@ class AttrAccessorWithDefaultTest < Test::Unit::TestCase def test_invalid_args assert_raise(RuntimeError) {@target.attr_accessor_with_default :foo} end + + def test_instance_with_such_attribute_can_be_marshaled + @target.attr_accessor_with_default(:foo, 'default') + @instance.foo = 'Hi' + assert_nothing_raised { Marshal.dump(@instance) } + end end -- 1.6.3.3