From 7ba538580c692b63e65c45b3cc973c02e5635897 Mon Sep 17 00:00:00 2001 From: Michael Parrish Date: Tue, 1 Mar 2011 13:17:19 -0600 Subject: [PATCH] Updating attr_accessor_with_default to work as expected with collections. [#6496 state:resolved] --- .../core_ext/module/attr_accessor_with_default.rb | 26 ++++++++++++++++---- .../module/attr_accessor_with_default_test.rb | 12 +++++++++ 2 files changed, 33 insertions(+), 5 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 e3259a0..23efb95 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 @@ -19,12 +19,28 @@ class Module # attr_accessor_with_default(:element_name) { name.underscore } # def attr_accessor_with_default(sym, default = Proc.new) - define_method(sym, block_given? ? default : Proc.new { default }) module_eval(<<-EVAL, __FILE__, __LINE__ + 1) - def #{sym}=(value) # def age=(value) - class << self; attr_accessor :#{sym} end # class << self; attr_accessor :age end - @#{sym} = value # @age = value - end # end + class << self; attr_reader :#{sym} end + + def #{sym}=(value) + class << self; attr_accessor :#{sym} end + @#{sym} = value + end EVAL + + if block_given? + define_method(sym, default) + else + module_eval(<<-EVAL, __FILE__, __LINE__ + 1) + def #{sym} + class << self; attr_accessor :#{sym} end + @#{sym} = self.class.#{ sym }.duplicable? ? self.class.#{ sym }.dup : self.class.#{ sym } + end + EVAL + end + + module_eval do + instance_variable_set "@#{ sym }", default + 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 b9b60c4..9953f36 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 @@ -25,6 +25,18 @@ class AttrAccessorWithDefaultTest < Test::Unit::TestCase assert_nil(@instance.foo) end + def test_default_with_collection + @target.attr_accessor_with_default :foo, [0, 0] + assert_equal([0, 0], @instance.foo) + @instance.foo[0] = :bar + assert_equal([:bar, 0], @instance.foo) + + new_instance = @target.new + assert_equal([0, 0], new_instance.foo) + new_instance.foo = [:bar, :baz] + assert_equal([:bar, :baz], new_instance.foo) + end + def test_invalid_args assert_raise(ArgumentError) {@target.attr_accessor_with_default :foo} end -- 1.7.1.1