Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Is it possible to break a loop from within an internal lambda function?

Reply
Thread Tools

Is it possible to break a loop from within an internal lambda function?

 
 
timr
Guest
Posts: n/a
 
      11-14-2010
This code works because 'exit' within the lambda within the block
stops the loop. However, I don't want to stop the program. I need to
use break rather than exit. But break won't work within that lambda--
the loop doesn't stop. I can of course reorganize the statement so
that it isn't a terse one-liner, and get it to work. But I would like
to be able to break the loop from within that lambda function if it is
possible. Somehow, I guess I need to make that break have a binding
to the method. Any ideas?!?

def solve_by_iter
counter = 1
loop do
yield counter
counter += 1
end
end
solve_by_iter { |test| lambda{puts test; exit}.call if (1..6).all?{|
num| test%num == (num-1)} }
#I want to use: solve_by_iter { |test| lambda{puts test; break}.call
if (1..6).all?{|num| test%num == (num-1)} }
 
Reply With Quote
 
 
 
 
Skye Shaw!@#$
Guest
Posts: n/a
 
      11-14-2010
On Nov 14, 12:54*am, timr <(E-Mail Removed)> wrote:
> This code works because 'exit' within the lambda within the block
> stops the loop. However, I don't want to stop the program. I need to
> use break rather than exit.
>
> #I want to use: solve_by_iter { |test| *lambda{puts test; break}.call
> if (1..6).all?{|num| test%num == (num-1)} }



This seems like an odd code arrangement.

What's wrong with returning a boolean value from the inner lambda and
breaking in the block?

solve_by_iter { |test| break if lambda{puts test; false}.call }

-Skye
 
Reply With Quote
 
 
 
 
Skye Shaw!@#$
Guest
Posts: n/a
 
      11-14-2010
On Nov 14, 1:18*am, "Skye Shaw!@#$" <(E-Mail Removed)> wrote:
> On Nov 14, 12:54*am, timr <(E-Mail Removed)> wrote:
>
> > #I want to use: solve_by_iter { |test| *lambda{puts test; break}.call
> > if (1..6).all?{|num| test%num == (num-1)} }

>
> What's wrong with returning a boolean value from the inner lambda and
> breaking in the block?
>
> solve_by_iter { |test| break if lambda{puts test; false}.call }


Though if you really, really -really, want to kill the call stack from
an arbitrary depth you could try (gulp):

def solve_by_iter
counter = 1
catch :break do
loop do
yield counter
counter += 1
end
end
end

solve_by_iter { |test| lambda{p test;throw :break}.call }

 
Reply With Quote
 
botp
Guest
Posts: n/a
 
      11-14-2010
On Sun, Nov 14, 2010 at 4:55 PM, timr <(E-Mail Removed)> wrote:
> solve_by_iter { |test| =A0lambda{puts test; exit}.call if (1..6).all?{|
> num| test%num =3D=3D (num-1)} }


try,

solve_by_iter { |test| break(lambda{puts test}.call) if
(1..6).all?{|num| test%num =3D=3D (num-1)} }

rare code, rare solution

kind regards -botp

 
Reply With Quote
 
timr
Guest
Posts: n/a
 
      11-14-2010
Thanks skye and botp. Both interesting solutions.

I also found this:
http://www.skorks.com/2010/05/ruby-p...-between-them/
"We get a LocalJumpError, what happened? Well, the break keyword is
used to break out of iteration, and we didn't have an iterator around
our proc, so we couldn't break out of anything, so Ruby tries to
punish us with an error. If we put an iterator around our proc,
everything would be fine:"

It gave me a better understanding of subtleties of lambdas and Procs.
Though, it looks like to make it work an iterator has to wrap the
calling of the proc more directly. I'll have to play with that more to
understand why. For the time being, I think break(lambda{}.call) is
the simplest solution.

 
Reply With Quote
 
w_a_x_man
Guest
Posts: n/a
 
      11-14-2010
On Nov 14, 2:54*am, timr <(E-Mail Removed)> wrote:
> This code works because 'exit' within the lambda within the block
> stops the loop. However, I don't want to stop the program. I need to
> use break rather than exit. But break won't work within that lambda--
> the loop doesn't stop. I can of course reorganize the statement so
> that it isn't a terse one-liner, and get it to work. But I would like
> to be able to break the loop from within that lambda function if it is
> possible. *Somehow, I guess I need to make that break have a binding
> to the method. Any ideas?!?
>
> def solve_by_iter
> * counter = 1
> * loop do
> * * yield counter
> * * counter += 1
> * end
> end
> solve_by_iter { |test| *lambda{puts test; exit}.call if (1..6).all?{|
> num| test%num == (num-1)} }
> #I want to use: solve_by_iter { |test| *lambda{puts test; break}.call
> if (1..6).all?{|num| test%num == (num-1)} }



solve_by_iter{|test|
if (1..6).all?{|num| test % num == num - 1 }
puts test
break
end
}

solve_by_iter{|test|
(1..6).all?{|num| test%num == num-1} and (puts test; break)
}

 
Reply With Quote
 
timr
Guest
Posts: n/a
 
      11-15-2010
On Nov 14, 4:46*am, w_a_x_man <(E-Mail Removed)> wrote:
> On Nov 14, 2:54*am, timr <(E-Mail Removed)> wrote:
>
>
>
>
>
>
>
>
>
> > This code works because 'exit' within the lambda within the block
> > stops the loop. However, I don't want to stop the program. I need to
> > use break rather than exit. But break won't work within that lambda--
> > the loop doesn't stop. I can of course reorganize the statement so
> > that it isn't a terse one-liner, and get it to work. But I would like
> > to be able to break the loop from within that lambda function if it is
> > possible. *Somehow, I guess I need to make that break have a binding
> > to the method. Any ideas?!?

>
> > def solve_by_iter
> > * counter = 1
> > * loop do
> > * * yield counter
> > * * counter += 1
> > * end
> > end
> > solve_by_iter { |test| *lambda{puts test; exit}.call if (1..6).all?{|
> > num| test%num == (num-1)} }
> > #I want to use: solve_by_iter { |test| *lambda{puts test; break}.call
> > if (1..6).all?{|num| test%num == (num-1)} }

>
> solve_by_iter{|test|
> * if (1..6).all?{|num| test % num == num - 1 }
> * * puts test
> * * break
> * end
>
> }
>
> solve_by_iter{|test|
> * (1..6).all?{|num| test%num == num-1} and (puts test; break)
>


That is also a clever solution. It uses 'and' for its ability control
whether a second statement should be evaluated rather than its boolean
sense. And I hadn't seen parentheses used to create multiline
statements like this before. That is the only reason I had been using
lambda before--to get a block of code with more than one line to be
executed as a single unit.

Similarly, break() is useful as previously suggested. The break() also
removes the need for a lambda statement. Combining solutions, and
using the if statement rather than 'and' which in my mind is slightly
easier to read, how about this (w/ slight refactoring of variable
names):

def solve_by_iter
counter = 1
loop do
yield(counter)
counter+=1
end
end

solve_by_iter{|numer| (puts numer; break) if (1..6).all?{|denom| numer
%denom == denom-1}}

Thanks guys, I learned a lot from your responses to this post.
Tim
 
Reply With Quote
 
botp
Guest
Posts: n/a
 
      11-15-2010
> solve_by_iter{|numer| (puts numer; break) if (1..6).all?{|denom| numer
> %denom == denom-1}}


in short, you can simply do

puts (1..1/0.0).find{|num| (1..6).all?{|denom| num % denom == denom - 1} }
59

kind regards -botp

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Type of lambda function returning a lambda function... Haochen Xie C++ 4 03-17-2013 11:23 PM
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
lambda vs non-lambda proc Steve Dogers Ruby 1 03-30-2009 10:11 PM
newbie: for loop within for loop question takayuki Python 2 06-16-2008 03:22 AM
Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?) Roman Suzi Python 13 01-07-2005 09:33 PM



Advertisments