B
Brian Adkins
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.
Brian Adkins
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.
Brian Adkins