Brian Adkins
10/25/2007 11:29:00 PM
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