On Oct 25, 2007, at 7:30 PM, Brian Adkins wrote:

> 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

Well, I'm pretty simple minded, so I would use a simple class to  
solve this problem. Something like

<code>
class Skipper
    def initialize(n)
       @n = n
    end
    def call
       yield if (@n -= 1) < 0
    end
end

skip_1 = Skipper.new(1)
a = []
4.times { |i| skip_1.call { a << i } }
a # => [1, 2, 3]

skip_2 = Skipper.new(2)
a = []
%w[a b c d].each { |w| skip_2.call { a << w } }
a # => ["c", "d"]
</code>

But it would appear you've already rejected that kind of solution.  
Why don't you like it?

Regards, Morton