tags:

views:

289

answers:

2

I find this line in the ZenTest source code:

result = @test_mappings.find { |file_re, ignored| filename =~ file_re }

The @test_mappings and result here are both Array object, but I didn't found 'find' method on Array class in ruby doc. I also tried it on irb:

irb(main):014:0> Array.respond_to? :find
=> false
irb(main):015:0> [1,2,3].find
LocalJumpError: no block given
        from (irb):15:in `find'
        from (irb):15:in `each'
        from (irb):15:in `find'
        from (irb):15
irb(main):016:0> [1,2,3].find{|x| x>1}
=> 2

Could any one explain it to me? How could find method also return an Array object? thanks in advance.

+5  A: 

Array includes the Enumerable module, which adds the find method.

In your example you tested Array.respond_to. This will only return true for class methods of Array. find is an instance method, so respond_to? must be invoked on an instance of the class.

>> a = Array.new
=> []
>> a.respond_to? :find
=> true
Gordon Wilson
If you don't want to create an instance just to see if it will respond to something, you could write Array.instance_methods.include?(:find)
Chuck
Good point, Chuck. (Though, you have to use a string not a symbol, e.g. "find")
Gordon Wilson
@Gordon, I am wonder if there is a way to allow me to know which class the method call is originated, such as in this case, to return Enumerable for the "find" method call.
eric2323223
@eric, good question. I don't know the answer off the top of my head. But, I'd like to. Want to post the question? I bet someone on here can explain it to the both of us.
Gordon Wilson
Ok, I'll try it.
eric2323223
+1  A: 

Another sometimes useful trick is calling the 'methods' function which lists all the methods available to the instance of the object and using the grep method to filter out for something specific. It also gives you a good picture of what standard methods are provided by base classes without referring to docs.

a = Array.new
=> []
>> a.methods.grep /find/
=> ["find", "find_all"]
paulthenerd
Nice tip, thanks.
eric2323223