Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Respond to missing #6169

Merged
merged 3 commits into from

4 participants

@marcandre

In Ruby 1.9.2, it's better to use respond_to_missing? than respond_to?, as it also handles method creation.

I see there are others in other rails packages, I'll create additional pull requests when I get a chance.

Thanks

@josevalim josevalim merged commit d6e2c81 into rails:master
@josevalim
Owner

Yes, please do!

@jonleighton
Collaborator

"as it also handles method creation" - what does this mean? Educate me, I am ignorant! Thanks

@marcandre

@jonleighton : as per the modified tests, obj.method(:via_missing) works. See also http://blog.marc-andre.ca/2010/11/methodmissing-politely.html

@jonleighton
Collaborator

Aha, thanks!

@sobrinho

any benefit on using respond_to_missing? here since we don't call super?

The benefit of using respond_to_missing? is not related to calling super or not. Please check http://blog.marc-andre.ca/2010/11/methodmissing-politely.html

nice to know, thanks @marcandre! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
4 activesupport/lib/active_support/multibyte/chars.rb
@@ -62,8 +62,8 @@ def method_missing(method, *args, &block)
# Returns +true+ if _obj_ responds to the given method. Private methods are included in the search
# only if the optional second parameter evaluates to +true+.
- def respond_to?(method, include_private=false)
- super || @wrapped_string.respond_to?(method, include_private)
+ def respond_to_missing?(method, include_private)
+ @wrapped_string.respond_to?(method, include_private)
end
# Returns +true+ when the proxy class can handle the string. Returns +false+ otherwise.
View
2  activesupport/lib/active_support/ordered_options.rb
@@ -36,7 +36,7 @@ def method_missing(name, *args)
end
end
- def respond_to?(name)
+ def respond_to_missing?(name, include_private)
true
end
end
View
6 activesupport/lib/active_support/time_with_zone.rb
@@ -311,10 +311,10 @@ def marshal_load(variables)
end
# Ensure proxy class responds to all methods that underlying time instance responds to.
- def respond_to?(sym, include_priv = false)
+ def respond_to_missing?(sym, include_priv)
# consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
- return false if sym.to_s == 'acts_like_date?'
- super || time.respond_to?(sym, include_priv)
+ return false if sym.to_sym == :acts_like_date?
+ time.respond_to?(sym, include_priv)
end
# Send the missing method to +time+ instance, and wrap result in a new TimeWithZone with the existing +time_zone+.
View
1  activesupport/test/core_ext/time_with_zone_test.rb
@@ -450,6 +450,7 @@ def test_instance_created_with_local_time_enforces_fall_dst_rules
def test_ruby_19_weekday_name_query_methods
%w(sunday? monday? tuesday? wednesday? thursday? friday? saturday?).each do |name|
assert_respond_to @twz, name
+ assert_equal @twz.send(name), @twz.method(name).call
end
end
View
9 activesupport/test/multibyte_chars_test.rb
@@ -458,6 +458,15 @@ def test_respond_to_knows_which_methods_the_proxy_responds_to
assert !''.mb_chars.respond_to?(:undefined_method) # Not defined
end
+ def test_method_works_for_proxyed_methods
+ assert_equal 'll', 'hello'.mb_chars.method(:slice).call(2..3) # Defined on Chars
+ chars = 'hello'.mb_chars
+ assert_equal 'Hello', chars.method(:capitalize!).call # Defined on Chars
+ assert_equal 'Hello', chars
+ assert_equal 'jello', 'hello'.mb_chars.method(:gsub).call(/h/, 'j') # Defined on String
+ assert_raise(NameError){ ''.mb_chars.method(:undefined_method) } # Not defined
+ end
+
def test_acts_like_string
assert 'Bambi'.mb_chars.acts_like_string?
end
View
8 activesupport/test/ordered_options_test.rb
@@ -77,4 +77,12 @@ def test_inheritable_options_inheritable_copy
assert copy.kind_of?(original.class)
assert_not_equal copy.object_id, original.object_id
end
+
+ def test_introspection
+ a = ActiveSupport::OrderedOptions.new
+ assert a.respond_to?(:blah)
+ assert a.respond_to?(:blah=)
+ assert_equal 42, a.method(:blah=).call(42)
+ assert_equal 42, a.method(:blah).call
+ end
end
Something went wrong with that request. Please try again.