diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 2ab6721fa2..2a345193af 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Invoking `Object#with_options` without a `&block` argument returns the
+ `ActiveSupport::OptionMerger` instance.
+
+ *Sean Doyle*
+
* `Rails.application.executor` hooks are now called around every tests.
This helps to better simulate request or job local state being reset around tests and prevent state
diff --git a/activesupport/lib/active_support/core_ext/object/with_options.rb b/activesupport/lib/active_support/core_ext/object/with_options.rb
index 1d46add6e0..a587ef6cc5 100644
--- a/activesupport/lib/active_support/core_ext/object/with_options.rb
+++ b/activesupport/lib/active_support/core_ext/object/with_options.rb
@@ -75,8 +75,27 @@ class Object
# end
# end
#
+ # When the block argument is omitted, the decorated Object instance is returned:
+ #
+ # module MyStyledHelpers
+ # def styled
+ # with_options style: "color: red;"
+ # end
+ # end
+ #
+ # # styled.link_to "I'm red", "/"
+ # # #=> I'm red
+ #
+ # # styled.button_tag "I'm red too!"
+ # # #=>
+ #
def with_options(options, &block)
option_merger = ActiveSupport::OptionMerger.new(self, options)
- block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
+
+ if block.nil?
+ option_merger
+ else
+ block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
+ end
end
end
diff --git a/activesupport/lib/active_support/option_merger.rb b/activesupport/lib/active_support/option_merger.rb
index 696bbedd41..4c7720af82 100644
--- a/activesupport/lib/active_support/option_merger.rb
+++ b/activesupport/lib/active_support/option_merger.rb
@@ -30,5 +30,9 @@ module ActiveSupport
@context.__send__(method, *arguments, &block)
end
end
+
+ def respond_to_missing?(*arguments)
+ @context.respond_to?(*arguments)
+ end
end
end
diff --git a/activesupport/test/option_merger_test.rb b/activesupport/test/option_merger_test.rb
index d77e05c990..b2126ba0b2 100644
--- a/activesupport/test/option_merger_test.rb
+++ b/activesupport/test/option_merger_test.rb
@@ -105,6 +105,14 @@ class OptionMergerTest < ActiveSupport::TestCase
assert_equal expected, @options
end
+ def test_with_options_no_block
+ local_options = { "cool" => true }
+ scope = with_options(@options)
+
+ assert_equal local_options, method_with_options(local_options)
+ assert_equal @options.merge(local_options), scope.method_with_options(local_options)
+ end
+
private
def method_with_options(options = {})
options