# Exit in a bloc DRY way

**URL:** <https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974>\
**Category:** Ruby\
**Created:** [February 18, 2007, 12:45pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974 "2007-02-18T12:45:19Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 12:45pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/1 "2007-02-18T12:45:19Z")

</div>

I wrote this code that’s running well…  
origin = false  
contact.each {|c| origin = true if c.from == parameter }  
nb -= 1 if origin

is there any way to write it in one line ? (exiting from the bloc when  
the condition is true)  
something like :  
contact.each {|c| nb -= 1; exit; if c.from == parameter }

tfyl

joss

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 1:03pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/2 "2007-02-18T13:03:21Z")

</div>

Hi,

I think this should do the job  
nb-=1 if contact.select{|c| c==parameter}.any?

it will return nb-1 if any contact matches parameter, or nil if none  
match

cheers,  
Dave

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 1:07pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/3 "2007-02-18T13:07:21Z")

</div>

Isn’t #find better than #select?

select wouldn’t break the first time a match was found, find would.  
Less time, less memory.

Aur S.

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 1:06pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/4 "2007-02-18T13:06:21Z")

</div>

A google turns up this:

In Ruby, break exits the block with value “nil”. The caller must check  
after each closure call to see if the value returned was “nil”, and  
break itself, if necessary. A side effect is that you can’t return  
“nil” from a block without terminating the calling structure. (As it  
happens, this is almost always acceptable.)

Use IRB to figure if indeed the standard methods that accept blocks do  
this checking.

contact.each {|c| nb -= 1; exit; if c.from == parameter } # the  
second ; is definitely wrong

Perhaps you meant:

contact.each {|c| if c.from == parameter; nb -= 1; break; end }

Well, if each is defined and the Enumerable mixin is mixed in (it  
usually is), you get #find for free, so:

## $ ri Enumerable#find -------------------------------------------------------- Enumerable#f ind enum.detect(ifnone = nil) {| obj | block } =\> obj or nil enum.find(ifnone = nil) {| obj | block } =\> obj or nil

* * *

```
 Passes each entry in _enum_ to _block_. Returns the first for wh

```

ich  
_block_ is not +false+. If no object matches, calls _ifnone_ and  
returns its result when it is specified, or returns +nil+

```
    (1..10).detect {|i| i % 5 == 0 and i % 7 == 0 } #=> nil
    (1..100).detect {|i| i % 5 == 0 and i % 7 == 0 } #=> 35

```

So how about:

nb = -1 if contact.find{|c| c.from == parameter }

?

This seems good.

Plug: Have a look at the adopt-a-newbie thread

Aur S.

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 1:18pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/5 "2007-02-18T13:18:22Z")

</div>

On 2/18/07, SonOfLilit [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > cheers,  
> > Dave  
> > Isn’t #find better than #select?
> 
> select wouldn’t break the first time a match was found, find would.  
> Less time, less memory.
> 
> Aur S.

I’d do:

nb-=1 if contact.any?{|c| c.from==parameter}

Regards,  
George.

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 1:21pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/6 "2007-02-18T13:21:22Z")

</div>

> Isn’t #find better than #select?

Yes, I think you are correct.  
I am learning too and had not come across find before. Thankyou for  
the information.

Cheers,  
Dave

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 1:26pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/7 "2007-02-18T13:26:23Z")

</div>

On 2/18/07, George O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’d do:
> 
> nb-=1 if contact.any?{|c| c.from==parameter}
> 
> Regards,  
> George.

Wow, #any? can do this? Thanks for teaching me a cool idiom!

On 2/18/07, Sharon P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Yes, I think you are correct.  
> I am learning too and had not come across find before. Thankyou for  
> the information.
> 
> Cheers,  
> Dave

Then let me repeat that plug: Check out the adopt-a-newbie thread please  
🙂

Aur S.

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 1:45pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/8 "2007-02-18T13:45:26Z")

</div>

On 2007-02-18 13:05:29 +0100, SonOfLilit [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) said:

> $ ri Enumerable#find
> 
> > ```
> > contact.each {|c| origin = true if c.from == parameter }
> > nb -= 1 if origin
> > 
> > ```
> > 
> > is there any way to write it in one line ? (exiting from the bloc when  
> > the condition is true)  
> > something like :  
> > contact.each {|c| nb -= 1; exit; if c.from == parameter }
> > 
> > tfyl
> > 
> > joss

thanks a lot !! I love Ruby for that… start from one point … and  
logically go to the DRY way… with  
Rubist help…

where is this thread ‘adopt a newbie’ … ?

joss

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [February 18, 2007, 2:16pm UTC](https://www.ruby-forum.com/t/exit-in-a-bloc-dry-way/85974/9 "2007-02-18T14:16:27Z")

</div>

Here in the list. How do you read the list? Myself, I’m subscribed to  
it in my gmail account and have it all in a label, so for me it’s  
simply in the first page.

If you can’t find it, google for ruby adopt-a-newbie.

Aur S.
