rails/rails — pull request #17527 by claudiob (2014-11-06 04:43:12+00:00)
Title: Speed up `acts_like?` by not using `respond_to?`

This commit modifies the internal way in which classes need to override
`Object#acts_like?` in order to declare that they behave like a given class.

The public API of `acts_like?` is not affected: all the uses of `acts_like?`
will still work and will be faster, since the new implementation gets rid
of `respond_to?` in the method implementation.

---

More details on this commit.

According to the [Rails guides](http://edgeguides.rubyonrails.org/active_support_core_extensions.html#acts-like-questionmark-duck):

> The method acts_like? provides a way to check whether some class acts like some other class based on a simple convention: a class that provides the same interface as String defines
>
> def acts_like_string?
> end
>
> which is only a marker, its body or return value are irrelevant.

This convention was introduced seven years ago in f28eef9a and is implemented as:

```ruby
def acts_like?(duck)
respond_to? :"acts_like_#{duck}?"
end
```

This PR makes the implementation above _more performant_ by:

* removing the need to call `respond_to?`
* removing the need to add internal methods like `acts_like_string?` to the objects

[This gist](https://gist.github.com/claudiob/35d6ea765aeeb86d24c1) shows an example benchmark comparing old and new implementation,
based off the code of [acts_like_test.rb](https://github.com/rails/rails/blame/master/activesupport/test/core_ext/object/acts_like_test.rb).