Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the block argument to Array#first do?

Tags:

ruby

My memory got the worst of me and I forgot about Array#find.

So I wrote some code which used Array#first to get the first item matching a condition:

first_even_num = [1,2,3].first { |x| x % 2 == 0 }

This does not work, it just returns the first element of the array no matter what the condition is. The block is not being called at all:

[1,2,3].first { |x| exit }
puts "the program did not exit"

I've accepted that Array#first does not do what imagined it to, but I'm curious why the aforementioned examples don't raise errors.

Looking at the 2.3.1 source, the only documented argument is an integer representing the number of returned results.

I don't really know C but this is what the underlying Array#first method has as a parameter signature:

rb_ary_first(int argc, VALUE *argv, VALUE ary)

I'm just wondering why the block provided to Array#first does not raise an error if it does nothing.

like image 826
max pleaner Avatar asked Jun 04 '26 00:06

max pleaner


2 Answers

You can pass blocks to any method, absolutely any. If it doesn't need the block, it simply won't use it. It is not an error (because block is not one of the arguments. It's a separate input for a method)

like image 156
Sergio Tulentsev Avatar answered Jun 07 '26 07:06

Sergio Tulentsev


There's some simple rules about Ruby and blocks.

  1. You can pass a block to any method.

  2. That method may choose to run your block zero or more times at any point in time from the present to the distant future.

  3. You must read the documentation or method implementation to understand if, how and when a block will be exercised. There is no other way of knowing.

Your example here of passing a block to a method that's not expecting one is consistent with these rules. Effectively it's being run zero times and has no bearing on the outcome of the first call.

like image 44
tadman Avatar answered Jun 07 '26 09:06

tadman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!