Question from Loop

a=[[1,2,3],[2,3,4],[54,6,5]]

for i in a
  for j in i
    puts j
    if j.eql?2
      break
    end
  end
end

This break breaks the inner loop, but I would like to get out of the
both loop once condition is reached. Can I do this without using flag
kind of thing?

RAJ

···

--
Posted via http://www.ruby-forum.com/.

Raja gopalan wrote in post #1136996:

a=[[1,2,3],[2,3,4],[54,6,5]]

This break breaks the inner loop, but I would like to get out of the
both loop once condition is reached. Can I do this without using flag
kind of thing?

I'd do as below :

a=[[1,2,3],[2,3,4],[54,6,5]]
prc = proc { break }
for i in a
  for j in i
    puts j
    if j.eql?2
      prc.call
    end
  end
end

**output**
1
2

···

--
Posted via http://www.ruby-forum.com/\.

ok Thank you Arup Rakshit

···

--
Posted via http://www.ruby-forum.com/.

I don't see the point of two loops for this, so how about --

a = [[1,2,3], [2,3,4], [54,6,5]].flatten
( puts (x = a.shift); break if x.eql?(2) ) until a.empty?

FWIW,

···

On Mon, Feb 17, 2014 at 11:25 PM, Raja gopalan <lists@ruby-forum.com> wrote:

a=[[1,2,3],[2,3,4],[54,6,5]]

for i in a
  for j in i
    puts j
    if j.eql?2
      break
    end
  end
end

This break breaks the inner loop, but I would like to get out of the
both loop once condition is reached. Can I do this without using flag
kind of thing?

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com

twitter: @hassan

a=[[1,2,3],[2,3,4],[54,6,5]]

for i in a
  for j in i
    puts j
    if j.eql?2
      break
    end
  end
end

First, I would write this like:

a = [[1,2,3], [2,3,4], [54,6,5]]

a.each do |i|
  i.each do |j|
    puts j
    break if j == 2
  end
end

(actually, I also wouldn't use one-letter variable names)

This break breaks the inner loop, but I would like to get out of the
both loop once condition is reached. Can I do this without using flag
kind of thing?

Second, you can achieve this by wrapping your code in a method
and using return:

def handle(array)
  array.each do |i|
    i.each do |j|
      puts j
      return if j == 2
    end
  end
end

a = [[1,2,3], [2,3,4], [54,6,5]]
handle(a)

Output:
1
2

Regards,
Marcus

···

Am 18.02.2014 08:25, schrieb Raja gopalan:

--
GitHub: stomar (Marcus Stollsteimer) · GitHub
PGP: 0x6B3A101A

You can use catch throw for this:

catch :outer do
  for i in a
    for j in i
      puts j
      if j.eql?2
        throw :outer
      end
    end
  end
end

Cheers

robert

···

On Tue, Feb 18, 2014 at 8:25 AM, Raja gopalan <lists@ruby-forum.com> wrote:

a=[[1,2,3],[2,3,4],[54,6,5]]

for i in a
  for j in i
    puts j
    if j.eql?2
      break
    end
  end
end

This break breaks the inner loop, but I would like to get out of the
both loop once condition is reached. Can I do this without using flag
kind of thing?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

hi Hassan Schroeder,

You code works, but my intention was to have two loops and breaking two
loops when the condition is met. Thank you.

hi Robert Klemme,

Your Code ROCKS!!!, This is what I expected and I am not even aware of
these type of coding 'catch :outer do'. Thank you.

RAJ

···

--
Posted via http://www.ruby-forum.com/.

hi Robert Klemme,

"a.each {|i| i.each {|j| p j; break if j == 2} or break}"

This is an another interesting code. You really Rock with Ruby CODE!!!

RAJ

···

--
Posted via http://www.ruby-forum.com/.

hi Arup Rakshit

It's not working for me,

My output is this

1
2
3
2
3
4
54
6
5

I am using Ruby 1.8.7 that might be cause of this?

···

--
Posted via http://www.ruby-forum.com/.

This is very unclear, and in 1.8 proc behaves differently.

Introducing a method and using return instead of break would be
much clearer (see my other post).

Also possible: throw and catch

a = [[1,2,3], [2,3,4], [54,6,5]]

catch :quit do
  a.each do |i|
    i.each do |j|
      puts j
      throw(:quit) if j == 2
    end
  end
end

Regards,
Marcus

···

Am 18.02.2014 08:49, schrieb Arup Rakshit:

Raja gopalan wrote in post #1136996:

a=[[1,2,3],[2,3,4],[54,6,5]]

This break breaks the inner loop, but I would like to get out of the
both loop once condition is reached. Can I do this without using flag
kind of thing?

I'd do as below :

a=[[1,2,3],[2,3,4],[54,6,5]]
prc = proc { break }
for i in a
  for j in i
    puts j
    if j.eql?2
      prc.call
    end
  end
end

**output**
1
2

--
GitHub: stomar (Marcus Stollsteimer) · GitHub
PGP: 0x6B3A101A

Robert Klemme wrote in post #1137187:

···

On Tue, Feb 18, 2014 at 8:25 AM, Raja gopalan <lists@ruby-forum.com> > wrote:

catch :outer do
  for i in a
    for j in i
      puts j
      if j.eql?2
        throw :outer
      end
    end
  end
end

+1 for teaching this one to me. :slight_smile:

--
Posted via http://www.ruby-forum.com/\.

You're welcome! You can even use this to transport information:

irb(main):001:0> x = catch(:foo) { throw :foo }
=> nil
irb(main):002:0> x
=> nil
irb(main):003:0> x = catch(:foo) { throw :foo, 123 }
=> 123
irb(main):004:0> x
=> 123

Cheers

robert

···

On Wed, Feb 19, 2014 at 12:16 PM, Raja gopalan <lists@ruby-forum.com> wrote:

hi Hassan Schroeder,

You code works, but my intention was to have two loops and breaking two
loops when the condition is met. Thank you.

hi Robert Klemme,

Your Code ROCKS!!!, This is what I expected and I am not even aware of
these type of coding 'catch :outer do'. Thank you.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Raja gopalan wrote in post #1136999:

hi Arup Rakshit

It's not working for me,

May be. My version is -

C:\ruby>ruby -v hello.rb
ruby 1.9.3p448 (2013-06-27) [i386-mingw32]
1
2

C:\ruby>

···

--
Posted via http://www.ruby-forum.com/\.

unknown wrote in post #1137119:

prc = proc { break }
1
2

This is very unclear, and in 1.8 proc behaves differently.

Thanks for letting me know.

Introducing a method and using return instead of break would be
much clearer (see my other post).

Yes, that was nice. I actually wanted to show OP, how to break out from
the loop.

Also possible: throw and catch

a = [[1,2,3], [2,3,4], [54,6,5]]

catch :quit do
  a.each do |i|
    i.each do |j|
      puts j
      throw(:quit) if j == 2
    end
  end
end

Nice earning for me.

···

Am 18.02.2014 08:49, schrieb Arup Rakshit:

Regards,
Marcus

--
Posted via http://www.ruby-forum.com/\.

Robert Klemme wrote in post #1137197:

You're welcome! You can even use this to transport information:

irb(main):001:0> x = catch(:foo) { throw :foo }
=> nil
irb(main):002:0> x
=> nil
irb(main):003:0> x = catch(:foo) { throw :foo, 123 }
=> 123
irb(main):004:0> x
=> 123

Again I went to the doc link -
Module: Kernel (Ruby 2.1.0) . I
understood what happened with above code.

From the doc one line I don't understand - when no **arg** is given,
`catch` assigns a **new unique object** to throw. this is useful for
**nested catch**.

Can you explain this with a example ?

···

--
Posted via http://www.ruby-forum.com/\.

Robert Klemme wrote in post #1137197:

irb(main):001:0> x = catch(:foo) { throw :foo }
=> nil
irb(main):002:0> x
=> nil
irb(main):003:0> x = catch(:foo) { throw :foo, 123 }
=> 123
irb(main):004:0> x
=> 123

Cheers

robert

Ok Thank you.

···

--
Posted via http://www.ruby-forum.com/\.

In general, it is considered bad practice to use exceptions for flow
control.
Exceptions indicate, and should be used for, cases where something
unexpected happened and you are trying to recover.
I strongly encourage you not to use them in this way.

The have seen several good alternatives to your problem:
        * flatten the array and use one loop
        * make a method and use return

···

"ruby-talk" <ruby-talk-bounces@ruby-lang.org> wrote on 02/19/2014 07:41:21 AM:

From: Arup Rakshit <lists@ruby-forum.com>
To: ruby-talk@ruby-lang.org
Date: 02/19/2014 07:41 AM
Subject: Re: break statement in Loop
Sent by: "ruby-talk" <ruby-talk-bounces@ruby-lang.org>

Robert Klemme wrote in post #1137197:

> You're welcome! You can even use this to transport information:
>
> irb(main):001:0> x = catch(:foo) { throw :foo }
> => nil
> irb(main):002:0> x
> => nil
> irb(main):003:0> x = catch(:foo) { throw :foo, 123 }
> => 123
> irb(main):004:0> x
> => 123

Again I went to the doc link -
http://www.ruby-doc.org/core-2.1.0/Kernel.html#method-i-catch . I
understood what happened with above code.

From the doc one line I don't understand - when no **arg** is given,
`catch` assigns a **new unique object** to throw. this is useful for
**nested catch**.

Can you explain this with a example ?

--
Posted via http://www.ruby-forum.com/\.

In general, it is considered bad practice to use exceptions for flow
control.
Exceptions indicate, and should be used for, cases where something
unexpected happened and you are trying to recover.

These are no exceptions. Notice this:

Exceptions: raise...rescue
Flow control: catch...throw

I strongly encourage you not to use them in this way.

In Ruby this was invented intentionally to allow for such kind of _flow
control_. I agree, one should use is sparingly but there are situations
where it comes handy. Personally I can't remember the last time I used it
though. :slight_smile:

The have seen several good alternatives to your problem:
        * flatten the array and use one loop
        * make a method and use return

There's also another one

irb(main):001:0> a=[[1,2,3],[2,3,4],[54,6,5]]
=> [[1, 2, 3], [2, 3, 4], [54, 6, 5]]
irb(main):002:0> a.each {|i| i.each {|j| p j; break if j == 2} or break}
1
2
=> nil

Works also if the element is not found in the first sub array:

irb(main):006:0> a.each {|i| i.each {|j| p j; break if j == 4} or break}
1
2
3
2
3
4
=> nil

You can see that it completely iterates if the condition does not match:

irb(main):007:0> a.each {|i| i.each {|j| p j; break if j == 999} or break}
1
2
3
2
3
4
54
6
5
=> [[1, 2, 3], [2, 3, 4], [54, 6, 5]]

If we learn more about the problem that is to be solved here we may come up
with even better solutions.

Cheers

robert

···

On Wed, Feb 19, 2014 at 1:59 PM, <HANSEM1@nationwide.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Dear Arup,

Basically instead of

catch(:foo) { throw :foo }

You can write

catch { |foo| throw foo }

Look again:

catch(:foo) { |arg| p arg; throw arg }
# :foo
# => nil

catch { |arg| p arg; throw arg }
# #<Object:0x000000025ab778>
# => nil

It creates for you (and for free) a unique instance of Object and
yields it to the block.

I couldn't come out with a good code example where this could be useful.
At least we have two stylist way of writing it! :wink:

https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/23675/diff/

Best regards,
Abinoam Jr.

···

On Wed, Feb 19, 2014 at 9:41 AM, Arup Rakshit <lists@ruby-forum.com> wrote:

Robert Klemme wrote in post #1137197:

You're welcome! You can even use this to transport information:

irb(main):001:0> x = catch(:foo) { throw :foo }
=> nil
irb(main):002:0> x
=> nil
irb(main):003:0> x = catch(:foo) { throw :foo, 123 }
=> 123
irb(main):004:0> x
=> 123

Again I went to the doc link -
http://www.ruby-doc.org/core-2.1.0/Kernel.html#method-i-catch . I
understood what happened with above code.

From the doc one line I don't understand - when no **arg** is given,
`catch` assigns a **new unique object** to throw. this is useful for
**nested catch**.

Can you explain this with a example ?

--
Posted via http://www.ruby-forum.com/\.