From cf6dc4378388d046ecc2bca8e1658ee253918d82 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Luciano=20Germ=C3=A1n=20Panaro?= Date: Fri, 21 Nov 2008 12:29:53 -0200 Subject: [PATCH] Added Object#try_* using method_missing --- .../lib/active_support/core_ext/object/misc.rb | 28 +++++++++++++++---- .../test/core_ext/object_and_class_ext_test.rb | 16 +++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/object/misc.rb b/activesupport/lib/active_support/core_ext/object/misc.rb index 50f824c..778ce13 100644 --- a/activesupport/lib/active_support/core_ext/object/misc.rb +++ b/activesupport/lib/active_support/core_ext/object/misc.rb @@ -72,16 +72,32 @@ class Object respond_to? "acts_like_#{duck}?" end - # Tries to send the method only if object responds to it. Return +nil+ otherwise. - # + # Tries to send the method only if object responds to it. Return +nil+ otherwise. Accepts calls with arguments and blocks. + # Can also be used as dynamic method: try_a_method + # # ==== Example : # - # # Without try + # #Without try # @person ? @person.name : nil # - # With try + # #With try # @person.try(:name) - def try(method) - send(method) if respond_to?(method, true) + # + # #With dynamic try + # @person_try_name + # + # #With arguments and block + # 'Hello'.try(:sub, 'llo') { |match| 'y' } #returns 'Hey' + def try(method, *args, &block) + send(method, *args, &block) if respond_to?(method, true) + end + + # Allow try to be accessed with "try_method" + def method_missing(method_id, *args, &block) + if method_id.to_s =~ /^try_(\w+)$/ + try($1, *args, &block) + else + super + end 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 fbdce56..ad0351a 100644 --- a/activesupport/test/core_ext/object_and_class_ext_test.rb +++ b/activesupport/test/core_ext/object_and_class_ext_test.rb @@ -271,4 +271,20 @@ class ObjectTryTest < Test::Unit::TestCase assert_equal 5, @string.try(:size) end + def test_argument_forwarding + assert_equal 'Hey', @string.try(:sub, 'llo', 'y') + end + + def test_block_forwarding + assert_equal 'Hey', @string.try(:sub, 'llo') { |match| 'y' } + end + + def test_dynamic_existing_method + assert_equal 'Hey', @string.try_sub('llo') { |match| 'y' } + end + + def test_dynamic_nonexisting_method + assert_nil @string.try_undefined_method + end + end -- 1.5.6.3