From 04998cd0c92a13332844d04145a4ede3184c7bd0 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 27 Jul 2012 12:33:02 -0500 Subject: Add Object#try! with the old NoMethodError raising behavior --- activesupport/CHANGELOG.md | 2 +- .../lib/active_support/core_ext/object/try.rb | 14 ++++++++++++ .../test/core_ext/object_and_class_ext_test.rb | 26 +++++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) (limited to 'activesupport') diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 0e7a16aa96..cf32e2d7a0 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,6 +1,6 @@ ## Rails 4.0.0 (unreleased) ## -* `Object#try` will now return nil instead of raise a NoMethodError if the receiving object does not implement the method *DHH* +* `Object#try` will now return nil instead of raise a NoMethodError if the receiving object does not implement the method, but you can still get the old behavior by using the new `Object#try!` *DHH* * `Time#change` now works with time values with offsets other than UTC or the local time zone. *Andrew White* diff --git a/activesupport/lib/active_support/core_ext/object/try.rb b/activesupport/lib/active_support/core_ext/object/try.rb index a2d5caa7df..9974b61078 100644 --- a/activesupport/lib/active_support/core_ext/object/try.rb +++ b/activesupport/lib/active_support/core_ext/object/try.rb @@ -37,6 +37,16 @@ class Object public_send(*a, &b) if respond_to?(a.first) end end + + # Same as #try, but will raise a NoMethodError exception if the receiving is not nil and + # does not implemented the tried method. + def try!(*a, &b) + if a.empty? && block_given? + yield self + else + public_send(*a, &b) + end + end end class NilClass @@ -53,4 +63,8 @@ class NilClass def try(*args) nil end + + def try!(*args) + nil + end end diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb index 5dd965f405..ec7dd6d4fb 100644 --- a/activesupport/test/core_ext/object_and_class_ext_test.rb +++ b/activesupport/test/core_ext/object_and_class_ext_test.rb @@ -108,6 +108,18 @@ class ObjectTryTest < ActiveSupport::TestCase assert_nil @string.try(method, 'llo', 'y') end + def test_nonexisting_method_bang + method = :undefined_method + assert !@string.respond_to?(method) + assert_raise(NoMethodError) { @string.try!(method) } + end + + def test_nonexisting_method_with_arguments_bang + method = :undefined_method + assert !@string.respond_to?(method) + assert_raise(NoMethodError) { @string.try!(method, 'llo', 'y') } + end + def test_valid_method assert_equal 5, @string.try(:size) end @@ -124,7 +136,7 @@ class ObjectTryTest < ActiveSupport::TestCase assert_nil nil.try(:to_s) assert_nil nil.try(:to_i) end - + def test_false_try assert_equal 'false', false.try(:to_s) end @@ -139,6 +151,18 @@ class ObjectTryTest < ActiveSupport::TestCase assert_equal false, ran end + def test_try_with_private_method_bang + klass = Class.new do + private + + def private_method + 'private method' + end + end + + assert_raise(NoMethodError) { klass.new.try!(:private_method) } + end + def test_try_with_private_method klass = Class.new do private -- cgit v1.2.3