On Oct 25, 7:18 pm, Morton Goldberg <m_goldb... / ameritech.net> wrote:
> On Oct 25, 2007, at 6:40 PM, Brian Adkins wrote:
>
>
>
> > Consider the following code:
>
> > first = true
> > 3.times do
> >   if first
> >     first = false
> >   else
> >     puts 'foo'
> >   end
> >   ...
> > end
>
> > I'd like to be able to do the following instead:
>
> > 3.times do
> >   skip_first { puts 'foo' }
> >   ...
> > end
>
> > However, I'm pretty sure that's impossible - especially when you
> > consider running the above code twice would require state to be
> > initialized twice, so I expect some initialization outside the loop is
> > necessary.
>
> > So, what's the most elegant way to solve this?
>
> > Here are a couple I've come up with minus some implementation details.
> > They work, but I'm not very pleased with either one. I don't recall
> > ever needing 'n' to be other than 1, but it feels strange to not
> > generalize it. I also realize it's more typical to want to execute
> > code only on the first loop invocation, but I had the opposite need
> > when this question arose.
>
> > # Use an object for state
> > skip_first = SkipN.new(1)
> > 3.times do
> >   skip_first.run { puts 'hi' }
> >   ...
> > end
>
> > # Use a closure for state
> > skip_first = skipn(1)
> > 3.times do
> >   skip_first.call lambda { puts 'hi' }
> >   ...
> > end
>
> > I experimented with using a binding, but I discovered that a new
> > binding is created each time times invokes the block, so apparently
> > it's not possible to introduce a variable within the lexical scope of
> > the block for the duration of the 3.times invocations - or I missed
> > something.
>
> It's not entirely clear to me what you are trying to accomplish, so
> this may way off base.

What I'm trying to accomplish is a convenient way to execute a block
of code on every iteration except the first (or only on the first
iteration).

> For some reason you are ignoring that Integer#times passes an index
> into its block,

Yes, that's because a loop index will not always be available. The
times example was just an example. Consider:

foo.each do |bar|
  skip_first { ... }
  ...
end