From 2bd2d853da78c248b1d50add92ce21f43430abe9 Mon Sep 17 00:00:00 2001 From: Guilherme Mansur Date: Tue, 21 May 2019 14:45:04 -0400 Subject: Able to initalize default value for thread_mattr_* Added the ability to initialize `thread_mattr_*` methods with default values like so: ``` ruby class MyClass thread_attr_reader :foo, default: :foo thread_attr_writer :bar, default: :bar thread_attr_accessor: baz do "baz" end end ``` This is consistent with the api exposed by `mattr_accessor`. --- activesupport/CHANGELOG.md | 8 +++++ .../module/attribute_accessors_per_thread.rb | 16 ++++++--- .../module/attribute_accessor_per_thread_test.rb | 38 +++++++++++++++------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index f20c7c92e6..dad7005eb1 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,11 @@ +* Allow initializing `thread_mattr_*` attributes via `:default` option + + class Scraper + thread_mattr_reader :client, default: Api::Client.new + end + + *Guilherme Mansur* + * Add `compact_blank` for those times when you want to remove #blank? values from an Enumerable (also `compact_blank!` on Hash, Array, ActionController::Parameters) diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb index a6e87aeb68..452a456a52 100644 --- a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb @@ -33,7 +33,7 @@ class Module # end # # Current.new.user # => NoMethodError - def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true) # :nodoc: + def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) # :nodoc: syms.each do |sym| raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) @@ -52,6 +52,9 @@ class Module end EOS end + + default_val = (block_given? && default.nil?) ? yield : default + Thread.current["attr_" + name + "_#{sym}"] = default_val unless default_val.nil? end end alias :thread_cattr_reader :thread_mattr_reader @@ -74,7 +77,7 @@ class Module # end # # Current.new.user = "DHH" # => NoMethodError - def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true) # :nodoc: + def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil) # :nodoc: syms.each do |sym| raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) @@ -93,6 +96,9 @@ class Module end EOS end + + default_val = (block_given? && default.nil?) ? yield : default + Thread.current["attr_" + name + "_#{sym}"] = default_val unless default_val.nil? end end alias :thread_cattr_writer :thread_mattr_writer @@ -136,9 +142,9 @@ class Module # # Current.new.user = "DHH" # => NoMethodError # Current.new.user # => NoMethodError - def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true) - thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor) - thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor) + def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk) + thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, &blk) + thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default) end alias :thread_cattr_accessor :thread_mattr_accessor end diff --git a/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb b/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb index e0e331fc91..c73ca0be0c 100644 --- a/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb +++ b/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb @@ -4,21 +4,37 @@ require "abstract_unit" require "active_support/core_ext/module/attribute_accessors_per_thread" class ModuleAttributeAccessorPerThreadTest < ActiveSupport::TestCase + class MyClass + thread_mattr_accessor :foo + thread_mattr_accessor :bar, instance_writer: false + thread_mattr_reader :shaq, instance_reader: false + thread_mattr_accessor :camp, instance_accessor: false + end + + class SubMyClass < MyClass + end + def setup - @class = Class.new do - thread_mattr_accessor :foo - thread_mattr_accessor :bar, instance_writer: false - thread_mattr_reader :shaq, instance_reader: false - thread_mattr_accessor :camp, instance_accessor: false + @class = MyClass + @subclass = SubMyClass + @object = @class.new + end - def self.name; "MyClass" end - end + def test_can_initialize_with_default_value + Thread.new do + @class.thread_mattr_accessor :baz, default: "default_value" + assert_equal "default_value", @class.baz + end.join + end - @subclass = Class.new(@class) do - def self.name; "SubMyClass" end - end + def test_can_initialize_with_a_block_as_default_value + Thread.new do + @class.thread_mattr_accessor :baz do + "default_value" + end - @object = @class.new + assert_equal "default_value", @class.baz + end.join end def test_should_use_mattr_default -- cgit v1.2.3