[Pasadenarb-general] great meeting tonight!

Matt Pulver matt+pasadenarb at quantumlab.net
Wed Jun 13 22:16:06 EDT 2007


Ok so I don't read emails and now I spam the list :)

Maybe this is what you're looking for?

100.max_times_until do |i|
  puts "doing something #{i}"
  sleep 1
  release.seconds_later?(3)
end

Put the boolean-valued method call last that determines when to exit,
which then becomes the return value of yield:

class Fixnum
  def max_times_until
    1.upto(self) do |i|
      break if yield i
    end
  end
end

Attached is a runnable demo.

Matt


On Wed, Jun 13, 2007 at 06:51:22PM -0700, Matt Pulver wrote:
> As you can see I didn't read your entire email :) - adding a single
> lambda with 2 {}'s seems pretty clean to me... doesn't even add any
> extra lines.
> 
> Matt
> 
> 
> On Wed, Jun 13, 2007 at 06:44:18PM -0700, Matt Pulver wrote:
> > Hi Nate,
> > 
> > Nice exercise in higher-order procedures. Well thanks to your
> > talk last night, I think simply wrapping a lambda around the
> > release.successful? call should do the trick:
> > 
> > 100.max_times_until lambda { release.successful? } do |i|
> >   puts "doing something #{i}"
> >   sleep 1
> > end
> > 
> > where max_times_until is defined as:
> > 
> > class Fixnum
> >   def max_times_until( procedure )
> >     1.upto(self) do |i|
> >       break if procedure.call
> >       yield i
> >     end
> >   end
> > end
> > 
> > Attached is a script that tests this, by simply checking to see if 3
> > seconds have passed.
> > 
> > Matt
> > 
> > 
> > On Wed, Jun 13, 2007 at 01:04:46PM -0700, Nathan Murray wrote:
> > > 
> > >    Steve,  I'd  be  interested  in hearing about Jruby, I don't know much
> > >    about it.
> > > 
> > >    I  have  a  ruby  question  for  you  guys. I'm working on workers and
> > >    managers  like  we  were  talking  about last night. My workers create
> > >    "Releases"  (each  time  the site needs to be pushed live a Release is
> > >    created).
> > > 
> > >    I want to loop over and check if the release is done. However, I don't
> > >    want  to infinite loop, I only want to check it, say, maybe 100 times.
> > >    So I have the code like the following more than once:
> > > 
> > >        i = 0
> > >        until release.successful? || i >= 100
> > >          puts "doing something #{i}"
> > >          i += 1
> > >        end
> > >    It  works okay, but I see this repetition and want to abstract it out.
> > >    "Fill  in the slots" you might say. What I want is a rubyish way to do
> > >    this like
> > >    100.times do ... or 0.upto(100) etc.
> > >    So my first attempt was something like
> > > 
> > >        100.max_times_until release.successful? do |i|
> > >          puts "doing something #{i}"
> > >        end
> > >    and max_time_until takes care of the iterator and yields i each time.
> > >    The problem is that "release.successful?" is evaluated at the time its
> > >    called and never again. So you never know if the status of the release
> > >    changed.  The  best I've come up with is to wrap "release.successful?"
> > >    in  a  lambda block. But this is a bit ugly. Can anyone think of a way
> > >    to give this a clean syntax and still achieve the desired effect?
> > >    I've attached my Integer extension and a rails-runnable test.
> > >    ======================
> > >    class Integer
> > >      def max_times_until(predicate)
> > >        i = 0
> > >        until predicate.call || i >= to_i
> > >          yield i
> > >          i +=1
> > >        end
> > >      end
> > >    end
> > >    =========================
> > >    require File.dirname(__FILE__) + '/../../test_helper'
> > >    class Incrementer
> > >      attr_accessor :incrementer
> > >      def initialize
> > >        @incrementer = 0
> > >      end
> > >      def successful?
> > >        return true if @incrementer >= 5
> > >        @incrementer += 1
> > >        false
> > >      end
> > >    end
> > >    class IntegerExtensionTest < Test::Unit::TestCase
> > >      def test_max_times
> > >        inc = Incrementer.new
> > >        10.max_times_until lambda { inc.successful? } do |i|
> > >          puts "try #{i} (#{inc.incrementer})"
> > >        end
> > >        i = 0
> > >        until release.successful? || i >= 100
> > >          puts "doing something #{i}"
> > >          i += 1
> > >        end
> > >      end
> > >     end
> > > 
> > >    On Jun 13, 2007, at 12:52 PM, Steve Holder wrote:
> > > 
> > >      Thanks  for  the  link,  Nate  - until our discussion last night, I
> > >      hadn't  realized  there actually was a practical difference between
> > >      Proc.new  &  lambda.  The video turned out better than I expected -
> > >      some  of it is a bit blurry, but the audio is good.  I'll hopefully
> > >      be  able  to post them in the next few days, for folks who couldn't
> > >      make it last night.
> > >      I  also realized we never discussed what to do at the next meeting.
> > >      Any volunteers for talks?  Jruby hit 1.0 a couple days ago, I could
> > >      do a short presentation on that if anyone beside me is interested.
> > >      -Steve
> > > 
> > >    On 6/12/07, Nate Daiger <[1]nate at heydsg.com> wrote:
> > > 
> > >      it was tons of fun.
> > >      here's some of that proc vs. lambda crapola we were talking about:
> > >      [2]http://samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby 
> > >      nate
> 
> > #!/usr/bin/env ruby
> > 
> > class Fixnum
> >   def max_times_until( procedure )
> >     1.upto(self) do |i|
> >       break if procedure.call
> >       yield i
> >     end
> >   end
> > end
> > 
> > class Time
> >   def seconds_later?(seconds)
> >     self + seconds < Time.now
> >   end
> > end
> > 
> > release = Time.new
> > 
> > 100.max_times_until lambda { release.seconds_later?(3) } do |i|
> >   puts "doing something #{i}"
> >   sleep 1
> > end
> 
> _______________________________________________
> Pasadenarb-general mailing list
> Pasadenarb-general at rubyforge.org
> http://rubyforge.org/mailman/listinfo/pasadenarb-general
-------------- next part --------------
#!/usr/bin/env ruby

class Fixnum
  def max_times_until
    1.upto(self) do |i|
      break if yield i
    end
  end
end

class Time
  def seconds_later?(seconds)
    self + seconds < Time.now
  end
end

release = Time.new

100.max_times_until do |i|
  puts "doing something #{i}"
  sleep 1
  release.seconds_later?(3)
end


More information about the Pasadenarb-general mailing list