From: Robert Klemme Date: 2004-08-10T19:26:16+09:00 Subject: Re: FirstEachLast, an extension to the Enumerable module. "Alexander Kellett" schrieb im Newsbeitrag news:20040810095807.GA13593@loki... > On Tue, Aug 10, 2004 at 06:51:15PM +0900, Robert Klemme wrote: > > I strongly disagree. All sorts of problems arise from this approach: > > notice my lack of agreement with myself in any case :) > > > - permanent modification of elements' types > > - method name collisions > > - member state collisions > > - thread problems (1 instance used during two parallel iterations) > > > > The index clearly belongs to the *iteration* and not the elements. > > Possible solutions: > > > > - yield not the instance but an iteration state that has the current item > > as member > > - use delegator (this avoids permanent changes but has still method > > collision problems) > > yes. i'd agree that it belongs to the iteration. > otherwise i would have coded up the thing i mentioned, > but... i've never seen an alternate so never bothered. > could you explain what you mean by delegator in this > sense? just a usage case example would do. i'd love > to code this up at some point but never took the time > to come up with a nice api. # NOT RECOMMENDED class IterationState attr_accessor :item, :pos def method_missing(*a,&b) item.send(*a,&b) end undef :to_s, :to_a, :hash # ... and others end module Enumerable def each_with_state st = IterationState.new each_with_index do |e, i| st.item = e st.pos = i yield st end self end end ar = %w{foo bar baz bubu} ar.each_with_state do |x| puts "position #{x.pos} elem #{x.item}" end > sorry but i dislike these paradigms instensly :/ > the iterator knows, Not necessarily so: class RandEnum include Enumerable def intialize(max=nil) @max=max; end def each loop { yield rand @max } end end > so why should i have to duplicate > code like this. especially in a detect loop this > is incredibly annoying as in many cases a temporary > must be used for the returned value as the last statement > in the loop has to be "old_value = current_value". You can use inject. > also having a temporary outside the loop and polluting > the outer block... is disgusts me... You can't solve it otherwise because you need state that survives each iteration step. That *must* be kept outside the block - either by using a local or inject. > maybe i'm just too > purist but stuff like this *could* be solved so i > see no reason against doing it :) > > thanks for the feedback, You're welcome. robert