2007/10/26, mortee <mortee.lists / kavemalna.hu>: > Brian Adkins wrote: > > On Oct 25, 10:28 pm, mortee <mortee.li... / kavemalna.hu> wrote: > >> I'd try something along these lines: > >> > >> # sets up a binding with a local variable _iteration = 0, and then > >> # creates a lambda which inherits this binding, and can use the variable > >> # note that the lambda also inherits any block given to skip_first, > >> # so it can also yield > >> > >> def skip_first(_skip_count = 1) > >> _iteration = 0 > >> lambda do |x| > >> yield x if _iteration >= _skip_count > >> _iteration += 1 > >> end > >> end > >> > >> # you can then pass the lambda returned by skip_first to any iterator, > >> # using the & notation > >> > >> 5.times &skip_first {|a| puts a} > >> 1 > >> 2 > >> 3 > >> 4 > > > > So how do you pass the "real" block to the iterator then? The main > > point of the iteration isn't the code that's skipped on the first > > iteration, but the main body of the iteration. For example: > > > > foo.each do |elem| > > skip_first do > > # processing to be skipped the first time > > # through the loop that may or may not use > > # elem > > end > > # other important processing using elem > > end > > Sorry, it wasn't clear to me by this whole thread but this last post > that you wanted code which doesn't skip elements, as well as code which > does. Oh, that eluded me as well. In that case it's certainly best to just use #each_with_index and use the index as you said. > The bad news is that I guess from inside the block passed to the > iterator, you have no way (at least no nice way) to keep track of the > iteration count, and make decisions based on it. You either have to call > each_with_index, and make use of the passed index, but this won't work > with other iterators. It does, if you use Enumerator: 17:26:33 ~$ irb -r enumerator irb(main):001:0> %w{foo bar baz}.to_enum(:each_with_index). irb(main):002:0* map {|e,i| i % 2 == 0 ? e : :empty} => ["foo", :empty, "baz"] irb(main):003:0> > You might also try to set up some global variable the first time your > block is run, and then utilize that. Note that this will get tricky even > when repeatedly running loops with skipping sections - not to mention > nested ones. I would not go down that road either. > So in any way, you will have to somehow estabilish what is considered > your "outermost" scope, and do some counting relative to that. (Just > consider how skipping would work if called from inside a nested loop. > Will it skip the first n iteration of the outer loop, or the inner one?) > > All in all, you'll almost certainly have to set up your skipping and > non-skipping code blocks while still *outside* the loop itself. This is > what e.g. the above proposed skip_first method would do, just hiding the > variable initialization part from the caller. Frankly, I believe this shows it's all not worth the effort. Checking the provided iteration counter is straightforward and easy to read and understand. Kind regards robert