respond_to matcher

19 views
Skip to first unread message

Arup Rakshit

unread,
Jul 4, 2014, 11:28:13 PM7/4/14
to rs...@googlegroups.com
Hi,

In the relish doc :-

https://www.relishapp.com/rspec/rspec-expectations/v/3-0/docs/built-in-matchers/respond-to-matcher

Note that this matcher relies entirely upon #respond_to?. If an object
dynamically responds to a message via #method_missing, *but does not indicate
this via #respond_to?*, then this matcher will give you false results.

What does the *..* line mean ?

The below test simply passes :-

#!/usr/bin/env ruby

class Foo
def method_missing(name,*args,&block)
self.class.send(:define_method, name) do
"#{name} has been defined dynamically"
end
end
end

rspec :-

require_relative "../test.rb"

describe Foo do
before { subject.foo }

it "defines #foo dynamically" do
expect(subject).to respond_to(:foo)
end
end

I am not able to connect the line I marked with *..* with this example.... :(

--
================
Regards,
Arup Rakshit
================
Debugging is twice as hard as writing the code in the first place. Therefore,
if you write the code as cleverly as possible, you are, by definition, not
smart enough to debug it.

--Brian Kernighan

Xavier Shay

unread,
Jul 4, 2014, 11:57:03 PM7/4/14
to rs...@googlegroups.com
Sorry I don't understand what you are either asking or saying.


> If an object dynamically responds to a message via #method_missing, *but does not indicate this via #respond_to?*, then this matcher will give you false results.

Correct. If an object is doing this, it has incorrectly implemented method_missing.

Arup Rakshit

unread,
Jul 5, 2014, 12:04:22 AM7/5/14
to rs...@googlegroups.com
On Friday, July 04, 2014 09:02:59 PM Xavier Shay wrote:
> Sorry I don't understand what you are either asking or saying.
>
> > If an object dynamically responds to a message via #method_missing,
>
> *but does not indicate this via #respond_to?*, then this matcher will
> give you false results.
>
> Correct. If an object is doing this, it has incorrectly implemented
> method_missing.
>

I would like to understand, why my test passed, as I didn't implement
#respond_to?.

Xavier Shay

unread,
Jul 5, 2014, 12:08:01 AM7/5/14
to rs...@googlegroups.com

On 4/07/2014 8:03 pm, Arup Rakshit wrote:
> On Friday, July 04, 2014 09:02:59 PM Xavier Shay wrote:
>> Sorry I don't understand what you are either asking or saying.
>>
>> > If an object dynamically responds to a message via #method_missing,
>>
>> *but does not indicate this via #respond_to?*, then this matcher will
>> give you false results.
>>
>> Correct. If an object is doing this, it has incorrectly implemented
>> method_missing.
>>
> I would like to understand, why my test passed, as I didn't implement
> #respond_to?.
ok my apologies, I understand now.

When you call "define_method", that actually makes the method on the
object, meaning that respond_to? returns true. You can see this by
adding the following line to your spec:

puts subject.respond_to?(:foo)

If you actually just use method_missing and don't define the method,
then the spec will fail:

class Foo
def method_missing(name,*args,&block)
"#{name} has been defined dynamically"
end
end

Hope that helps,
Xavier

Arup Rakshit

unread,
Jul 5, 2014, 12:49:02 AM7/5/14
to rs...@googlegroups.com
>
> If you actually just use method_missing and don't define the method,
> then the spec will fail:
>

Ahh. Get it.

Okay. So, now to make it pass, what I need to do, without using #define_method.

> class Foo
> def method_missing(name,*args,&block)
> "#{name} has been defined dynamically"
> end
> end
>
> Hope that helps,
> Xavier

Xavier Shay

unread,
Jul 5, 2014, 11:03:27 AM7/5/14
to rs...@googlegroups.com

On 4/07/2014 8:48 pm, Arup Rakshit wrote:
>> If you actually just use method_missing and don't define the method,
>> then the spec will fail:
>>
> Ahh. Get it.
>
> Okay. So, now to make it pass, what I need to do, without using #define_method.
Just implement respond_to?:

class Foo
def method_missing(name,*args,&block)
"#{name} has been defined dynamically"
end

def respond_to?(method_name, include_all=false)
true
end
end

Arup Rakshit

unread,
Jul 5, 2014, 11:20:17 AM7/5/14
to rs...@googlegroups.com
Thanks Xavier.
Reply all
Reply to author
Forward
0 new messages